Solved

# Permutation for the letters of a Phone Number

Posted on 2008-10-31
655 Views
Last Modified: 2013-11-26
I am trying to make a program that based on a phone number input the program permutates every possible combination of those letter that are associated with the number. Like the number 2 has the letters abc. I'm having trouble associating the arrays with the numbers. This isn't a homework assignment its just something i'm trying to figure out on my own. This program must be made in visual basic 2008
0
Question by:ajh305
• 17
• 15
33 Comments

LVL 59

Expert Comment

Try using the generic versions of classes like KeyValuePair(Of Integer, List(Of Char)).  OR List(Of String).

When you add values, the digit is the key and the value is a List or Array of the characters it represents.

Hope that helps.
0

Author Comment

How exactly would i use those?
0

LVL 59

Expert Comment

``````'Use of a dictionary may be better, it uses same concept as KeyValuePair but already has it in a collection

'Therefore, you will not have to recreate the wheel

Dim dict As New Dictionary(Of Integer, List(Of Char))()

'Setup list of valid characters

Dim chars As New List(Of Char)()

chars.Add("A")

chars.Add("B")

chars.Add("C")

'Add to dictionary for specified phone digit

dict.Add(2, chars)

'Clear list and repeat for next digit

chars.Clear()

chars.Add("D")

chars.Add("E")

chars.Add("F")

dict.Add(3, chars)

'When retrieving, you can just do this

'Therefore, you can match each digit of a phone number to its list and then selecting each iteration

Dim list As List(Of Char) = dict(2)

'Example iteration

For Each c As Char In dict(3)

'Do something

Next
``````
0

Author Comment

Could i use say case statements and have the program somehow read each number in the input and for those number asign the letters and display them all in a text box as an array? What i mean is say you have and input number of 7643736. It reads all the number and then implements each case? or is your way much easier?
0

LVL 59

Expert Comment

Will take a look in the morning as having a hard time visualizing the full solution both ways... The part that will give the hearthache is you are doing a probability so 7643736 which is 7 digits becomes 3*3*3*3*3*3*3 words.
0

Author Comment

How do i get it to read the input?
0

Author Comment

Lets use your first solution and work from there. now i'm working on how to get the program to read the number from a text box and output the answer to a text box so whenever you get a chance maybe you could answer those questions and if i figure it out i will let you know, Thanks
0

Author Comment

Here is what i have so far

Public Class Form1

Public Sub main()
End Sub
Private Sub generate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles generate.Click
'Use of a dictionary may be better, it uses same concept as KeyValuePair but already has it in a collection
'Therefore, you will not have to recreate the wheel
Dim dict As New Dictionary(Of Integer, List(Of Char))()

'Setup list of valid characters
Dim chars As New List(Of Char)()

chars.Add("A")
chars.Add("B")
chars.Add("C")
'Add to dictionary for specified phone digit
dict.Add(2, chars)

'Clear list and repeat for next digit
chars.Clear()
chars.Add("D")
chars.Add("E")
chars.Add("F")

dict.Add(3, chars)

chars.Clear()
chars.Add("G")
chars.Add("H")
chars.Add("I")

dict.Add(4, chars)

chars.Clear()
chars.Add("J")
chars.Add("K")
chars.Add("L")

dict.Add(5, chars)

chars.Clear()
chars.Add("M")
chars.Add("N")
chars.Add("O")

dict.Add(6, chars)

chars.Clear()
chars.Add("P")
chars.Add("Q")
chars.Add("R")
chars.Add("S")

dict.Add(7, chars)

chars.Clear()
chars.Add("T")
chars.Add("U")
chars.Add("V")

dict.Add(8, chars)

chars.Clear()
chars.Add("W")
chars.Add("X")
chars.Add("Y")
chars.Add("Z")

dict.Add(9, chars)

phonenumber.Text =

'When retrieving, you can just do this
'Therefore, you can match each digit of a phone number to its list and then selecting each iteration
Dim list As List(Of Char) = dict(2)

'Example iteration
For Each c As Char In dict(2)
'Do something
Next

End Sub
End Class

i don't know how to get it to read an input or display the output
0

LVL 59

Expert Comment

If using a Windows Form project, you just add say a TextBox for input and a Label OR something to that effect for displaying output.

For that you would just do this:

Dim phoneNo As String = phonenumber.Text 'if phonenumber is the name of your textbox control
0

Author Comment

Ok well after i dimension the phonenumber as the input how will the program read that and display each permutation of each number in the phone number. I'm kinda lost on how exactly to do this sorry.
0

LVL 59

Expert Comment

I was just answering the question on how to read the input / display output.  We will still need to figure out the algorithm in between to calculate the permutations.

phonenumber.Text ==> gets the value from your control on windows form
Dim phoneNo As String ==> dimensions local variable for program
Dim phoneNo As String = phonenumber.Text  ==> assigns value of textbox control to local variable

We can now use phoneNo in code to get the permutations.

I am trying to figure out the best calc routine...having a mental block on this...know I have seen this before on phone numbers and did something similar with text...just not coming immediately to mind.

Here is what I am thinking happens next.

For Each digit As Char In phone.ToCharArray
'Goes through each digit of your phone number
For Each c As Char In dict(digit)
'Goes through each letter associated to digit in phone number
'Thinking about here
Next
Next
0

LVL 59

Expert Comment

Sorry copy and paste error:

For Each digit As Char In phoneNo.ToCharArray
'Goes through each digit of your phone number
For Each c As Char In dict(digit)
'Goes through each letter associated to digit in phone number
'Thinking about here
Next
Next
0

Author Comment

Is there anyway you could post the full code that you have so far. Piecing it together is kind of a headache
0

Author Comment

Public Class Form1

Public Sub main()
End Sub
Private Sub generate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles generate.Click
'Use of a dictionary may be better, it uses same concept as KeyValuePair but already has it in a collection
'Therefore, you will not have to recreate the wheel
Dim dict As New Dictionary(Of Integer, List(Of Char))()

'Setup list of valid characters
Dim chars As New List(Of Char)()

chars.Add("A")
chars.Add("B")
chars.Add("C")
'Add to dictionary for specified phone digit
dict.Add(2, chars)

'Clear list and repeat for next digit
chars.Clear()
chars.Add("D")
chars.Add("E")
chars.Add("F")

dict.Add(3, chars)

chars.Clear()
chars.Add("G")
chars.Add("H")
chars.Add("I")

dict.Add(4, chars)

chars.Clear()
chars.Add("J")
chars.Add("K")
chars.Add("L")

dict.Add(5, chars)

chars.Clear()
chars.Add("M")
chars.Add("N")
chars.Add("O")

dict.Add(6, chars)

chars.Clear()
chars.Add("P")
chars.Add("Q")
chars.Add("R")
chars.Add("S")

dict.Add(7, chars)

chars.Clear()
chars.Add("T")
chars.Add("U")
chars.Add("V")

dict.Add(8, chars)

chars.Clear()
chars.Add("W")
chars.Add("X")
chars.Add("Y")
chars.Add("Z")

dict.Add(9, chars)

Dim phoneNo As String = phonenumber.Text ' ==> assigns value of textbox control to local variable

For Each digit As Char In phoneNo.ToCharArray
'Goes through each digit of your phone number
For Each c As Char In dict(2)
For Each c As Char In dict(3)
For Each c As Char In dict(4)
For Each c As Char In dict(5)
For Each c As Char In dict(6)
For Each c As Char In dict(7)
For Each c As Char In dict(8)
For Each c As Char In dict(9)

Next
Next
Next
Next
Next
Next
Next
Next
'Goes through each letter associated to digit in phone number
'Thinking about here
Next

End Sub
End Class

This is what i have so far but it doesn't like having that many c's
0

LVL 59

Expert Comment

I have been trying to say that I am thinking through the process.  You have more code in yours than I have in mine.  I can answer specific questions if you have thoughts on how your want to do this.

>>I am trying to figure out the best calc routine...having a mental block on this...know I have seen this before on phone numbers and did something similar with text...just not coming immediately to mind.

When I get something working, I will post.
0

Author Comment

Ok sorry i thought you already had the answer. I'll post anything else if i come up with something also.
0

LVL 59

Expert Comment

This is what I just updated my testing code to from your posting above.

Simplifies some things.
``````Public Function makeCharList(ByVal chars As String) As List(Of Char)

Dim charsList As New List(Of Char)()

For Each c As Char In chars.ToCharArray

charsList.Add(c)

Next

Return charsList

End Function

Sub Main()

'Use of a dictionary may be better, it uses same concept as KeyValuePair but already has it in a collection

'Therefore, you will not have to recreate the wheel

Dim dict As New Dictionary(Of Char, List(Of Char))()

Dim words As New List(Of String)() 'To store word possibilities

'Add digits

dict.Add("0", makeCharList(""))

dict.Add("1", makeCharList(""))

dict.Add("2", makeCharList("ABC"))

dict.Add("3", makeCharList("DEF"))

dict.Add("4", makeCharList("GHI"))

dict.Add("5", makeCharList("JKL"))

dict.Add("6", makeCharList("MNO"))

dict.Add("7", makeCharList("PQRS"))

dict.Add("8", makeCharList("TUV"))

dict.Add("9", makeCharList("WXYZ"))

Dim phoneNo As String = phonenumber.Text ' ==> assigns value of textbox control to local variable

'Goes through each digit of your phone number

For Each digit As Char In phoneNo.ToCharArray

''''''''''

If words.Count < 1 Then

words.Add("")

End If

Dim listTemp As List(Of String) = words

Dim charCount As Integer = dict(digit).Count

For i As Integer = 1 To charCount

words.AddRange(listTemp)

Next

''''''''''

'Not sure what to do here yet, but will use something like one of these to not have to hardcode each digit

'For Each c As Char In dict(digit)

'some code

'Next

'OR

'For i As Integer = 0 To charCount - 1

'some code

'Next

Next

For Each word As String In words

Console.WriteLine(word)

Next

Console.ReadLine()

End Sub
``````
0

LVL 59

Expert Comment

I knew the answer to this question:
>>I'm having trouble associating the arrays with the numbers.

The permutation part I am still thinking of.  See above as just figured I did find that using Char for key instead of Integer so that you can use the character array of String to lookup keys without having to hardcode each character as you said which is annoying.  Along those lines I just created a quick method to do creation of list so you can simplify those lines of code.

Regards,
Kevin
0

Author Comment

How do i get this to run with a button on my form application
0

LVL 59

Expert Comment

Actually for your benefit, since I am the only one posting to this you are not getting the full benefit of EE as there are other experts who may remember what is escaping me at the moment as this is definitely possible.

If you original question was simply on how to associate digits to their respective letters, think this part of the code solves that and you can start a new question and I will continue to offer input on that question but you will also get new experts taking a look at the permutation part.

Otherwise, you can use the request attention button and try to get more input on this question.

Either way, the point is wouldn't hurt to have more people looking at this so that you get a more timely solution.

Best regards,
Kevin
``````Public Function makeCharList(ByVal chars As String) As List(Of Char)

Dim charsList As New List(Of Char)()

For Each c As Char In chars.ToCharArray

charsList.Add(c)

Next

Return charsList

End Function

'''''''' USAGE ''''''''

Dim dict As New Dictionary(Of Char, List(Of Char))()

'Add digits

dict.Add("0", makeCharList(""))

dict.Add("1", makeCharList(""))

dict.Add("2", makeCharList("ABC"))

dict.Add("3", makeCharList("DEF"))

dict.Add("4", makeCharList("GHI"))

dict.Add("5", makeCharList("JKL"))

dict.Add("6", makeCharList("MNO"))

dict.Add("7", makeCharList("PQRS"))

dict.Add("8", makeCharList("TUV"))

dict.Add("9", makeCharList("WXYZ"))
``````
0

LVL 59

Expert Comment

Sorry, easiest way for me to test logic at times is to use a Console application since I am just testing code and not UI.  I will create a Windows Form application, so my future postings are congruent with yours.

You would move the code from the Main() sub to your button click sub you had above.

0

Author Comment

Ok i moved the code and so far i get a freezing program haha. i am sorry if you become impatient with me but i am just so new at this kind of stuff but after i get this down pat i will have an awesome understanding of everything. Thank you in advance
0

LVL 59

Expert Comment

I am not impatient with you at all.  I am frustrated with myself that I haven't got full solution for you yet. ;)
0

LVL 59

Accepted Solution

Kevin Cross earned 500 total points
This is not the prettiest solution most likely, but here is it.
+Used the makeCharList function I showed you before modified to remove spaces.
+Used dictionary to store the numbers.  Again, I think any key/value object with list of characters OR similar code construct would work here.  Using makeCharList, fill in each digit 0 - 9 of a phone number.
+Using for each loop, go through each digit of phone number.
+If character list for specified digit has values (i.e. 0 and 1 don't have letters), then put current words in a temp list and clear original list.
+Loop through each character corresponding to current digit and add each word from temp list with character appended to it.

This worked on your original test number and some others, but you can always post back if you find otherwise.
``````Public Function makeCharList(ByVal chars As String) As List(Of Char)

Dim charsList As New List(Of Char)()

For Each c As Char In chars.Trim().ToCharArray()

charsList.Add(c)

Next

Return charsList

End Function

Private Sub generate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles generate.Click

'Use of a dictionary may be better, it uses same concept as KeyValuePair but already has it in a collection

'Therefore, you will not have to recreate the wheel

Dim dict As New Dictionary(Of Char, List(Of Char))()

Dim words As New List(Of String)() 'To store word possibilities

Dim wordsTemp As New List(Of String)() 'Temp word lists as needed

Dim listTemp As New List(Of Char)() 'Temp character list

'Add digits

dict.Add("0", makeCharList(""))

dict.Add("1", makeCharList(""))

dict.Add("2", makeCharList("ABC"))

dict.Add("3", makeCharList("DEF"))

dict.Add("4", makeCharList("GHI"))

dict.Add("5", makeCharList("JKL"))

dict.Add("6", makeCharList("MNO"))

dict.Add("7", makeCharList("PQRS"))

dict.Add("8", makeCharList("TUV"))

dict.Add("9", makeCharList("WXYZ"))

Dim phoneNo As String = phonenumber.Text.Trim() ' ==> assigns value of textbox control to local variable

'Goes through each digit of your phone number

For Each digit As Char In phoneNo.ToCharArray()

listTemp = dict(digit)

If listTemp.Count > 0 Then

'''''''''' setup words list ''''''''''

wordsTemp.Clear()

If words.Count < 1 Then

wordsTemp.Add("")

Else

wordsTemp.AddRange(words)

words.Clear()

End If

''''''''''

For Each word As String In wordsTemp

For Each c As Char In listTemp

words.Add(word & c)

Next

Next

End If

Next

MsgBox(String.Format("Writing {0} words to list", words.Count))

lbWords.Items.Clear()

For Each word As String In words

lbWords.Items.Add(word)

Next

MsgBox("Generate process complete!")

End Sub
``````
0

LVL 59

Expert Comment

Think I forgot to mention that I used a ListBox object called lbWords on my form to store the results.  The ListBox items is a Collection itself, so to tighten the code you could just do this:

Change --
For Each word As String In words
lbWords.Items.Add(word)
Next

To --
lbWords.Items.AddRange(words.ToArray())
0

Author Comment

Ok i tried your codes and its giving me this stupid error.

Error      1      Name 'lbWords' is not declared.      C:\Users\Adam\Documents\Visual Studio 2008\Projects\WindowsApplication1\WindowsApplication1\Form1.vb      60      9      Lab 4
Error      2      Name 'lbWords' is not declared.      C:\Users\Adam\Documents\Visual Studio 2008\Projects\WindowsApplication1\WindowsApplication1\Form1.vb      62      13      Lab 4
0

Author Comment

Ok i got it thank you so much you have been an amazing help! I only hope that someday i could know what you know :) thanks again!
0

LVL 59

Expert Comment

You are most welcome.

Happy coding!
0

LVL 85

Expert Comment

(I haven't tried mwvisa1's submission)

This looked essentially like the problem I solved here:
http://www.experts-exchange.com/Programming/Languages/Q_21116627.html#11968082

So here is that solution modified for your phone numbers scenario:
``````Public Class Form1

Private letters As New Dictionary(Of String, String)

Private WithEvents bgw As New System.ComponentModel.BackgroundWorker

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

letters.Add("1", "1")

letters.Add("2", "abc")

letters.Add("3", "def")

letters.Add("4", "ghi")

letters.Add("5", "jkl")

letters.Add("6", "mno")

letters.Add("7", "pqrs")

letters.Add("8", "tuv")

letters.Add("9", "wxyz")

letters.Add("0", "0")

letters.Add("-", "")

letters.Add(" ", "")

letters.Add("(", "")

letters.Add(")", "")

bgw.WorkerReportsProgress = True

End Sub

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

If TextBox1.Text.Trim.Length > 0 Then

Button1.Enabled = False

Dim value, letter As String

Dim values As New List(Of String)

values = New List(Of String)

For i As Integer = 0 To TextBox1.TextLength - 1

value = TextBox1.Text.Substring(i, 1)

If letters.ContainsKey(value) Then

letter = letters.Item(value)

If letter <> "" Then

values.Add(letter)

End If

Else

MessageBox.Show("Invalid Phone Number")

Exit Sub

End If

Next

If values.Count > 0 Then

ProgressBar1.Value = 0

ListBox1.Items.Clear()

bgw.RunWorkerAsync(values)

End If

End If

End Sub

Private Sub bgw_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgw.DoWork

Dim values As List(Of String) = e.Argument

Dim sizes As New List(Of Integer)

Dim combinations As Integer

Dim i As Integer

Dim j As Integer

Dim remainder As Integer

Dim quotient As Integer

Dim combination As New List(Of String)

combinations = 1

For Each value As String In values

sizes.Add(value.Length)

combinations = combinations * value.Length

Next

For i = 0 To combinations - 1

combination.Clear()

For j = 1 To values.Count

combination.Add(Nothing)

Next

quotient = i \ sizes.Item(sizes.Count - 1) ' Integer Division

remainder = i Mod sizes.Item(sizes.Count - 1)

combination(values.Count - 1) = values.Item(values.Count - 1).Substring(remainder, 1)

For j = (sizes.Count - 2) To 0 Step -1

combination.Item(j) = values.Item(j).Substring(quotient Mod sizes.Item(j), 1)

quotient = quotient \ sizes.Item(j) ' Integer Division

Next

bgw.ReportProgress(CInt((i + 1) / combinations * 100), String.Join("", combination.ToArray))

If bgw.CancellationPending Then

Exit For

End If

Next

e.Result = combinations

End Sub

Private Sub bgw_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bgw.ProgressChanged

ProgressBar1.Value = e.ProgressPercentage

ListBox1.Items.Add(e.UserState)

End Sub

Private Sub bgw_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bgw.RunWorkerCompleted

Button1.Enabled = True

ProgressBar1.Value = 0

MessageBox.Show(e.Result & " combination(s)", "Done!")

End Sub

End Class
``````
Demo-App.jpg
0

Author Comment

mwvisa1 I was just wondering if you could maybe explain your code a little better i'm having trouble understanding it all.
0

LVL 59

Expert Comment

I tried to comment throughout and in my comment you accepted for solution I explained code some more, but will gladly explain more -- just need help with which pieces you are having difficulty understanding to save time in getting to what you need.
Also see Idle Mind had another solution.
0

LVL 59

Expert Comment

For Each digit As Char In phoneNo.ToCharArray()
'This takes each digit of phone number (e.g. 7643736, first character/digit is "7") one at a time.

listTemp = dict(digit) 'get the characters associated to each digit "P", "Q", "R", "S" in this case for "7"
'If number of characters is > 0 which we have 4, then run our routine
If listTemp.Count > 0 Then
'''''''''' setup words list ''''''''''
wordsTemp.Clear() 'dump temp word list
If words.Count < 1 Then 'catch for first case as no words already exist
wordsTemp.Add("")
Else 'otherwise when words exist, fill temp word list with all words
wordsTemp.AddRange(words)
words.Clear() 'clear word list
End If
''''''''''

'for each word in the temp wordlist, add a word with each character appended to it -- we will end up with 4 new words "P", "Q", "R", "S" after this step
For Each word As String In wordsTemp
For Each c As Char In listTemp
words.Add(word & c)
Next
Next
End If
Next

Does that help?  Or still unclear?
0

Author Comment

Ok thanks you answered the part i was having trouble with!
0

## Join & Write a Comment Already a member? Login.

### Suggested Solutions

Wouldnâ€™t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldnâ€™t it be good if you could write code like this? (CODE) In .NET 3.5, this is possibleâ€¦
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
This video discusses moving either the default database or any database to a new volume.
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custoâ€¦

#### 728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

#### Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!