parsing a string of digits

I want to take a string, split it and save it into an array and if there are numbers in it I want to identify the numbers and convert them into a string of letters for example I want to take 1450 and convert it to one thousand four hundred fifty. I've used a select case for smaller numbers, but there has to be an easier way for larger numbers. In the example below iI am also reversing the input string, which seems straight forward, but I also want to convert digits to words. Thanks

PrivateSub btnReverse_Click(ByVal senderAs System.Object,ByVal eAs System.EventArgs)Handles btnReverse.Click

Dim TempArray()AsString

Dim IndexAsInteger

txtOutput.Clear()

TempArray = txtInput.Text.Split(" ".ToCharArray)

TempArray.Reverse(TempArray)

For Index = 0To TempArray.GetUpperBound(0)

txtOutput.Text = txtOutput.Text & " " & ConvertNum(TempArray(Index))

Next

EndSub

PublicFunction ConvertNum(ByVal numAsString)AsString

SelectCase num

CaseIs = 0

Return "Zero"

CaseIs = 1

Return "One"

CaseIs = 2

Return "Two"

CaseIs = 3

Return "Three"

CaseIs = 4

Return "Four"

CaseIs = 5

Return "Five"

CaseIs = 6

Return "Six"

CaseIs = 7

Return "Seven"

CaseIs = 8

Return "Eight"

CaseIs = 9

Return "Nine"

CaseElse

Return num

EndSelect

EndFunction

[3329 byte] By [JimBoDH] at [2008-1-10]
# 1

Hi Jim,

This can be (and should) implemented as recursive function. I have a version written ín Ruby (modification of code from a Ruby tutorial) that can rather easily be translated to VB2005 if you want to have it. In it look up arrays are used for strings,. I don't dare to post the Ruby code unless you want it (and no one else has a VB version).

Regards

Csaba

CsabaU at 2007-10-3 > top of Msdn Tech,Visual Basic,Visual Basic Language...
# 2

Sure if no one else has a verson. It would be most helpful. Thanks.

Jim

JimBoDH at 2007-10-3 > top of Msdn Tech,Visual Basic,Visual Basic Language...
# 3

Hi again,

I made a quick translation to VB2005 from Ruby, the reason for the 'Rubish" variable names. This is my first BASIC code with recursion, ever!

Regards

Csaba

(PS - This is really a straighforward translation, and it shows how good VB8 is compared with old VB and BASIC versions)

Function numbers_in_english(ByVal number_to_translate As Int32) As String

' special case, not yet for negative numbers

If number_to_translate < 0 Then

Return "Please enter only positive numbers!"

ElseIf number_to_translate = 0 Then

Return "zero"

End If

' No more special cases! no more returns!

Dim number_as_string As String = "" ' This is the string we will return

' These array are used to look up english words for numbers,

' Since array is zero- based, fill "0:th place" with dummy value

Dim ones_place As String() = {"zero_never_used", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"}

Dim tens_place As String()= {"zero_never_used", "ten", "twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty" , "ninety"}

Dim teenagers As String() = {"zero_never_used", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"}

' digits_to_convert is the part of number_to_translate right now.

Dim digits_to_convert As Int32 = number_to_translate \ 100 ' How many hundreds?

' reminder is how much of number_to_convert we still have left to convert

Dim reminder As Int32 = number_to_translate - digits_to_convert * 100 ' Subtract of those hundreds

If digits_to_convert > 0 Then ' Now here is the recursion

Dim hundreds_as_string As String = numbers_in_english(digits_to_convert)

number_as_string = number_as_string & hundreds_as_string & " hundred"

If reminder > 0 Then ' So we don't write as 'twohundredfifty-one'

number_as_string = number_as_string & " "

End If

End If

digits_to_convert = reminder \ 10 ' How many tens left

reminder = reminder - digits_to_convert * 10 ' Subtract of those teens

If digits_to_convert > 0 Then

If digits_to_convert = 1 And reminder > 0 Then ' 11 ...19

' Since we can't write 'teenty-two' instead of twelve

' we have to make a special exception

number_as_string = number_as_string & teenagers(reminder)

' Since we took care of all digits in

' reminder already, we have nothing left to convert

reminder = 0

Else ' 20 ...99

number_as_string = number_as_string & tens_place(digits_to_convert)

End If

If reminder > 0 Then ' so we don't write 'sixtyfour'

number_as_string = number_as_string & "-"

End If

End If

' Only single digits left in remider to convert, do it if it is larger than zero

If reminder > 0 Then

number_as_string = number_as_string & ones_place(reminder)

End If

' ready!

Return number_as_string

End Function ' of numbers_in_english

CsabaU at 2007-10-3 > top of Msdn Tech,Visual Basic,Visual Basic Language...
# 4

Hi ALL,

The above function has the letter "s" missing from seven in the code.

I have just tried it.

No mention of billions, millions or thousands though.

The function is okay otherwise.

Regards,

John.

Code Snippet

Public Class Form1

'The next highlighted line should be one line of code in the code window.>>

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

MessageBox.Show(numbers_in_english(987654321))

End Sub

Function numbers_in_english(ByVal number_to_translate As Int32) As String

' special case, not yet for negative numbers

If number_to_translate < 0 Then

Return "Please enter only positive numbers!"

ElseIf number_to_translate = 0 Then

Return "zero"

End If

' No more special cases! no more returns!

Dim number_as_string As String = "" ' This is the string we will return

' These array are used to look up english words for numbers,

' Since array is zero- based, fill "0:th place" with dummy value

Dim ones_place As String() = {"zero_never_used", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"}

Dim tens_place As String() = {"zero_never_used", "ten", "twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty", "ninety"}

Dim teenagers As String() = {"zero_never_used", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"}

' digits_to_convert is the part of number_to_translate right now.

Dim digits_to_convert As Int32 = number_to_translate \ 100 ' How many hundreds?

' reminder is how much of number_to_convert we still have left to convert

Dim reminder As Int32 = number_to_translate - digits_to_convert * 100 ' Subtract of those hundreds

If digits_to_convert > 0 Then ' Now here is the recursion

Dim hundreds_as_string As String = numbers_in_english(digits_to_convert)

number_as_string = number_as_string & hundreds_as_string & " hundred"

If reminder > 0 Then ' So we don't write as 'twohundredfifty-one'

number_as_string = number_as_string & " "

End If

End If

digits_to_convert = reminder \ 10 ' How many tens left

reminder = reminder - digits_to_convert * 10 ' Subtract of those teens

If digits_to_convert > 0 Then

If digits_to_convert = 1 And reminder > 0 Then ' 11 ...19

' Since we can't write 'twenty-two' instead of twelve

' we have to make a special exception

number_as_string = number_as_string & teenagers(reminder)

' Since we took care of all digits in

' reminder already, we have nothing left to convert

reminder = 0

Else ' 20 ...99

number_as_string = number_as_string & tens_place(digits_to_convert)

End If

If reminder > 0 Then ' so we don't write 'sixtyfour'

number_as_string = number_as_string & "-"

End If

End If

' Only single digits left in remider to convert, do it if it is larger than zero

If reminder > 0 Then

number_as_string = number_as_string & ones_place(reminder)

End If

' ready!

Return number_as_string

End Function ' of numbers_in_english

End Class

JohnOliver(UK)MSP,VSIP at 2007-10-3 > top of Msdn Tech,Visual Basic,Visual Basic Language...
# 5

Hi again,

here is a version with also thousend and millions. I leave billion as excersise.

Regards

Csaba

Code Snippet

Function numbers_in_english(ByVal number_to_translate As Int32) As String

' special case, not yet for negative numbers

If number_to_translate < 0 Then

Return "Please enter only positive numbers!"

ElseIf number_to_translate = 0 Then

Return "zero"

End If

' No more special cases! no more returns!

Dim number_as_string As String = "" ' This is the string we will return

' These array are used to look up english words for numbers, Since array is zero- based, fill "0:th place" with dummy value

Dim ones_place As String() = {"zero_never_used", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"}

Dim tens_place As String() = {"zero_never_used", "ten", "twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty", "ninety"}

Dim teenagers As String() = {"zero_never_used", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"}

' >1 000 000 digits_to_convert is the part of number_to_translate right now.

Dim digits_to_convert As Int32 = number_to_translate \ 1000000 ' How many millions?

' reminder is how much of number_to_convert we still have left to convert

Dim reminder As Int32 = number_to_translate - digits_to_convert * 1000000 ' Subtract of those millions

If digits_to_convert > 0 Then ' Now here is the recursion - build up the million string

number_as_string &= numbers_in_english(digits_to_convert) & " million"

If reminder > 0 Then number_as_string &= " " ' So we don't write as millionone

End If

' 1000 - 9999 digits_to_convert is the part of number_to_translate right now.

digits_to_convert = reminder \ 1000 ' How many thousands left

reminder = reminder - digits_to_convert * 1000 ' Subtract of those thousands

If digits_to_convert > 0 Then ' Now here is the recursion - build up the tousend string

number_as_string &= numbers_in_english(digits_to_convert) & " thousand"

If reminder > 0 Then number_as_string &= " " ' So we don't write as thousandone

End If

' 100 - 999 digits_to_convert is the part of number_to_translate right now.

digits_to_convert = reminder \ 100 ' How many hundreds?

' reminder is how much of number_to_convert we still have left to convert

reminder = reminder - digits_to_convert * 100 ' Subtract of those hundreds

If digits_to_convert > 0 Then ' Now here is the recursion - build up the hundred string

number_as_string &= numbers_in_english(digits_to_convert) & " hundred"

If reminder > 0 Then number_as_string &= " " ' So we don't write as 'twohundredfifty-one'

End If

digits_to_convert = reminder \ 10 ' How many tens left

reminder = reminder - digits_to_convert * 10 ' Subtract of those teens

If digits_to_convert > 0 Then

If digits_to_convert = 1 And reminder > 0 Then ' 11 ...19

' Since we can't write 'teenty-two' instead of twelve we have to make a special exception

number_as_string &= teenagers(reminder)

' Since we took care of all digits in reminder already, we have nothing left to convert

reminder = 0

Else ' 20 ...99

number_as_string &= tens_place(digits_to_convert)

End If

' so we don't write 'sixtyfour'

If reminder > 0 Then number_as_string &= "-"

End If

' Only single digits left in reminder to convert, do it if it is larger than zero

If reminder > 0 Then number_as_string &= ones_place(reminder)

' ready!

Return number_as_string

End Function ' of numbers_in_english

CsabaU at 2007-10-3 > top of Msdn Tech,Visual Basic,Visual Basic Language...
# 6

Thanks for all your solutions. Here's what I've come up with. However, I am also reversing the string without using the built-in functions.

Private Sub btnReverse_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnReverse.Click

Dim strInput As String, pos As Integer

txtOutput.Text = ""

strInput = txtInput.Text

For pos = Len(strInput) To 1 Step -1

txtOutput.Text = txtOutput.Text & ConvertNum(Mid$(strInput, pos, 1))

Next

End Sub

Public Function ConvertNum(ByVal num As String) As String

Select Case num

Case Is = 0

Return "Zero"

Case Is = 1

Return "One"

Case Is = 2

Return "Two"

Case Is = 3

Return "Three"

Case Is = 4

Return "Four"

Case Is = 5

Return "Five"

Case Is = 6

Return "Six"

Case Is = 7

Return "Seven"

Case Is = 8

Return "Eight"

Case Is = 9

Return "Nine"

Case Else

Return num

End Select

End Function

JimBoDH at 2007-10-3 > top of Msdn Tech,Visual Basic,Visual Basic Language...
# 7

Hi Jim,

Based on you post, you need to convert the numbers to the word.

I recommend you use the HashTable object to save the basic numbers and corresponding words. You can then use this basic numbers to compose the other numbers, for example 0-9, 10, 100. I think it is the easy way by using the HashTable to convert numbers to the words. For more information about how to use the HashTable class, please visit: http://msdn2.microsoft.com/en-us/library/system.collections.hashtable.aspx. Here is the code snippet to convert 0-9999 to the words.

Code Snippet

Public Class Form1

Dim myHT As New Hashtable()

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

myHT.Add("0", " zero ")

myHT.Add("1", " one ")

myHT.Add("2", " two ")

myHT.Add("3", " three ")

myHT.Add("4", " four ")

myHT.Add("5", " five ")

myHT.Add("6", " six ")

myHT.Add("7", " seven ")

myHT.Add("8", " eight ")

myHT.Add("9", " nine ")

myHT.Add("11", " eleven ")

myHT.Add("12", " twelve ")

myHT.Add("13", " thirteen ")

myHT.Add("14", " fourteen ")

myHT.Add("15", " fifteen ")

myHT.Add("16", " sixteen ")

myHT.Add("17", " seventeen ")

myHT.Add("18", " eighteen ")

myHT.Add("19", " nineteen ")

myHT.Add("20", " twenty ")

myHT.Add("30", " thirty ")

myHT.Add("40", " fourty ")

myHT.Add("50", " fifty ")

myHT.Add("60", " sixty ")

myHT.Add("70", " seventy ")

myHT.Add("10", " ten ")

myHT.Add("80", " eighty ")

myHT.Add("90", " ninety ")

myHT.Add("100", " hundred ")

myHT.Add("1000", " thousand ")

myHT.Add("100000", " lakh ")

myHT.Add("1000000", " million ")

myHT.Add("1000000000", " billion ")

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

MessageBox.Show(Me.convert2words("9999"))

End Sub

Function convert2words(ByVal digits As String) As String

Dim words As String = String.Empty

Select Case digits.ToString.Length

Case Is = 1

words = Me.myHT.Item(digits)

Case Is = 2

If (Convert.ToInt32(digits) <= 20) Then

words = Me.myHT.Item(digits)

Else

Dim tendigit As String = digits(0)

Dim singledigit As String = digits(1)

words = Me.myHT.Item(tendigit + "0") + Me.myHT.Item(singledigit)

End If

Case Is = 3

Dim singledigit As String = digits(2)

Dim tendigit As String = digits(1)

Dim hundreddigit As String = digits(0)

words = Me.myHT.Item(hundreddigit) + Me.myHT.Item("100") + Me.myHT.Item(tendigit + "0") + Me.myHT.Item(singledigit)

Case Is = 4

Dim singledigit As String = digits(3)

Dim tendigit As String = digits(2)

Dim hundreddigit As String = digits(1)

Dim thousanddigit As String = digits(0)

words = Me.myHT.Item(thousanddigit) + Me.myHT.Item("1000") + Me.myHT.Item(hundreddigit) + Me.myHT.Item("100") + Me.myHT.Item(tendigit + "0") + Me.myHT.Item(singledigit)

Case Is = 5

Case Is = 6

Case Is = 7

Case Is = 8

Case Is = 9

Case Else

Throw New Exception("Not support so many digits")

End Select

Return words

End Function

End Class

Best regards,

Riquel.

RiquelDong–MSFT at 2007-10-3 > top of Msdn Tech,Visual Basic,Visual Basic Language...