VB: Word Scramble using StrConv and StringBuilder

05:59 / Posted by Terry /

I had answered a fellow who wanted to know how you can write a word scramble in Visual Basic. For this problem, I will provide two examples, one in VB6, and the other in VB .Net. The VB6 version will simple take the string in a textbox and scramble the letters. The VB.Net version will take a string, separate each word, and scramble the words themselves. I thought this would be an interesting demonstration since working with character elements in VB strings has the tendency to be a bit of a pain. This will demonstrate using a character array to work with individual elements, using the StrConv function in VB6 to convert to a byte array, and using the StringBuilder class in VB.Net for more efficient string appends.

Below is the VB6 version 1:
Option Explicit
Private Sub CommandButton1_Click()
Dim x, pos As Integer
Dim char As String
Dim s() As String

'Re-dimension the array to the size of the string in the textbox
ReDim s(Len(TextBox1.Text)) As String

'Assign each character to an element in the array
For x = 1 To Len(TextBox1.Text)
s(x) = Mid(TextBox1.Text, x, 1)
Next

'For 1 to the size of the array, mix up the letters
For x = 1 To UBound(s)
'Pos is a random place in the array
pos = Int((Len(TextBox1.Text) - 1) * Rnd) + 1

'temporarily assign the temp character to our random letter
char = s(pos)

'Swap the characters, using the temp character to assign from the overwriten
'element
s(pos) = s(x)
s(x) = char
Next

'Clear the textbox and concat the value with each element in the array
TextBox1.Text = ""
For x = 1 To UBound(s)
TextBox1.Text = TextBox1.Text & s(x)
Next
End Sub

Private Sub UserForm_Click()
Randomize
End Sub

The above is a fairly simple. Take two elements in an array, and swaps them. This is pretty much the same as the VB.Net version below with a few exceptions. Alternatively, we can use the StrConv function to eliminate having to go through each element in the string and assign it to the array. This method is demonstrated below:

VB6 Version 2 Code:
Private Sub Command1_Click()
Dim b() As Byte
Dim temp As Byte
Dim s As String
Dim x, pos As Integer

s = Text1.Text

ReDim b(Len(s)) As Byte
b = StrConv(s, vbFromUnicode)

For x = LBound(b) To UBound(b)
pos = Int((Len(Text1.Text) - 1) * Rnd) + 1

temp = b(pos)

b(pos) = b(x)
b(x) = temp
Next

s = StrConv(b, vbUnicode)
End Sub


The above code is much cleaner in my opinion. In the StrConv() function, notice the use of the parameter vbFromUnicode andvbUnicode. The reason for this is that VB uses Unicode strings. Had we just assigned b the value of s, we would have an array twice as large, and the scramble code would need to take into account the additional byte that Unicode characters contain, otherwise we would have some undefined results.

Below is the VB .Net version 1. I used the first algorithm from above as the model:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Initialize the random number generator
Randomize()
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim s_array() As String = Split(TextBox1.Text, " ")
Dim s, final As String
Dim c As Char
Dim x, i, pos As Integer

'We need to cycle through the array of strings set in the dim statement above
For x = LBound(s_array) To (UBound(s_array))

'If the current place in the array is greater than the lower bound and less than or
'equal to the last string, then we need to add a space in between words
If (x > LBound(s_array)) And (x <= UBound(s_array)) Then
TextBox1.Text = TextBox1.Text & " "
End If

'For each letter in the current word, cycle through and use a
'simple character swap with a random position in the string
For i = 0 To (s_array(x).Length - 1)
'Get random position in the string
pos = CInt(Int(s_array(x).Length * Rnd()))

'Store the character so swap temporarily so it does not get lost
c = s_array(x).Chars(pos)

'Set current letter with the letter to get swapped
s_array(x) = s_array(x).Insert(pos, s_array(x).Chars(i))
s_array(x) = s_array(x).Remove(pos + 1, 1)

'Set current letter to the stored letter, completing the swap
s_array(x) = s_array(x).Insert(i, c)
s_array(x) = s_array(x).Remove(i + 1, 1)
Next

'If we are on the first word, clear the textbox and set to current element
'in the array, otherwise concat the textbox with current value
If (x = LBound(s_array)) Then
TextBox1.Text = s_array(x)
Else
TextBox1.Text = TextBox1.Text & s_array(x)
End If
Next
End Sub
End Class

While the above code works, there are a few issues with it. First, just like in the VB6 version, the handling of individual characters is not clean. We can assign the string to an array of characters directly and be better off. Also, the use of inserts and removes for individual characters are ugly and inefficient. .Net strings are immutable, so for each insert and remove, a copy of the string is created, making things very slow. Fortunately .Net offers the StringBuilder class for doing just this sort of operation. Below is the modified .Net version taking advantage of the direct assignment to a character array and using the StringBuilder class.

Below is the Vb.Net code modified (Version 2):
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim s_array() As String = Split(TextBox1.Text, " ")
Dim b() As Char
Dim c As Char
Dim x, i, pos As Integer
Dim tmpStrngBldr As System.Text.StringBuilder = New System.Text.StringBuilder()

'We need to cycle through the array of strings set in the dim statement above
For x = LBound(s_array) To (UBound(s_array))

'If the current place in the array is greater than the lower bound and less than or
'equal to the last string, then we need to add a space in between words
If (x > LBound(s_array)) And (x <= UBound(s_array)) Then
tmpStrngBldr.Append(" ")
End If

b = s_array(x)

'For each letter in the current word, cycle through and use a
'simple character swap with a random position in the string
For i = LBound(b) To UBound(b)
'Get random position in the string
pos = CInt(Int(UBound(b) * Rnd()))

'Store the character so swap temporarily so it does not get lost
c = b(pos)

'Set current letter with the letter to get swapped
b(pos) = b(i)

'Set current letter to the stored letter, completing the swap
b(i) = c
Next

‘Store the swaped word in our stringbuilder
tmpStrngBldr.Append(b)
Next

'assign the textbox the value in our string builder
TextBox1.Text = tmpStrngBldr.ToString
tmpStrngBldr = Nothing
End Sub

7 comments:

匿名 on 2010年2月3日 13:29

[B]NZBsRus.com[/B]
Lose Laggin Downloads Using NZB Files You Can Rapidly Search High Quality Movies, PC Games, MP3 Singles, Applications & Download Them at Maxed Out Rates

[URL=http://www.nzbsrus.com][B]Usenet Search[/B][/URL]

匿名 on 2010年2月18日 12:47

Infatuation casinos? into this unversed [url=http://www.realcazinoz.com]casino[/url] advisor and wing it denigrate online casino games like slots, blackjack, roulette, baccarat and more at www.realcazinoz.com .
you can also swear to our redesigned [url=http://freecasinogames2010.webs.com]casino[/url] subsistence at http://freecasinogames2010.webs.com and conquer determined thorough currency !
another unsurpassed [url=http://www.ttittancasino.com]casino spiele[/url] consider is www.ttittancasino.com , in proffer german gamblers, away with a conceal with in manumitted online casino bonus.

匿名 on 2010年3月13日 18:10

sustain seeking all to figure this gratis [url=http://www.casinoapart.com]casino[/url] hand-out at the prime [url=http://www.casinoapart.com]online casino[/url] be opportune for known to with 10's of well-versed [url=http://www.casinoapart.com]online casinos[/url]. actions [url=http://www.casinoapart.com/articles/play-roulette.html]roulette[/url], [url=http://www.casinoapart.com/articles/play-slots.html]slots[/url] and [url=http://www.casinoapart.com/articles/play-baccarat.html]baccarat[/url] at this [url=http://www.casinoapart.com/articles/no-deposit-casinos.html]no best up a measure against casino[/url] , www.casinoapart.com
the finest [url=http://de.casinoapart.com]casino[/url] in the involvement corporation UK, german and all to the world. so in search the treatment of the paragon [url=http://es.casinoapart.com]casino en linea[/url] corroborate us now.

匿名 on 2010年3月19日 11:07

It isn't hard at all to start making money online in the underground world of [URL=http://www.www.blackhatmoneymaker.com]blackhat make money[/URL], You are far from alone if you don't know what blackhat is. Blackhat marketing uses little-known or not-so-known methods to build an income online.

匿名 on 2010年8月18日 11:54

Amiable dispatch and this post helped me alot in my college assignement. Gratefulness you on your information.

匿名 on 2011年8月24日 13:46

[url=http://www.kamagrashop.pl]potencja[/url], thwart my site.

匿名 on 2013年1月15日 06:47

[url=http://www.23planet.com]casinos online[/url], also known as agreed casinos or Internet casinos, are online versions of pile up ("chunk and mortar") casinos. Online casinos aid gamblers to liking incorrect looking after ingredient in and wager on casino games unconstrained the Internet.
Online casinos superficially insist on odds and payback percentages that are comparable to land-based casinos. Some online casinos law higher payback percentages as a physic looking in espouse of performance shindy games, and some publish payout match audits on their websites. Assuming that the online casino is using an fittingly programmed indefinitely compress up generator, board games like blackjack fundamental an established borderline edge. The payout model up after these games are established to the mid the rules of the game.
Differing online casinos lease in fall pint-sized or lay one's hands on their software from companies like Microgaming, Realtime Gaming, Playtech, Main Imposture Technology and CryptoLogic Inc.

发表评论