How can I print out all possible letter combinations a given phone number can represent?

前端 未结 30 2081
逝去的感伤
逝去的感伤 2020-12-22 18:01

I just tried for my first programming interview and one of the questions was to write a program that given a 7 digit telephone number, could print all possible combinations

相关标签:
30条回答
  • 2020-12-22 18:45

    Here is the working code for the same.. its a recursion on each step checking possibility of each combinations on occurrence of same digit in a series....I am not sure if there is any better solution then this from complexity point of view.....

    Please let me know for any issues....

    import java.util.ArrayList;
    
    
    public class phonenumbers {
    
        /**
         * @param args
         */
        public static String mappings[][] = {
            {"0"}, {"1"}, {"A", "B", "C"}, {"D", "E", "F"}, {"G", "H", "I"},
            {"J", "K", "L"}, {"M", "N", "O"}, {"P", "Q", "R", "S"}, 
            {"T", "U", "V"}, {"W", "X", "Y", "Z"}
        };
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
    
            String phone = "3333456789";
            ArrayList<String> list= generateAllnums(phone,"",0);
        }
    
        private static ArrayList<String> generateAllnums(String phone,String sofar,int j) {
            // TODO Auto-generated method stub
    
            //System.out.println(phone);
            if(phone.isEmpty()){
                System.out.println(sofar);
                for(int k1=0;k1<sofar.length();k1++){
                    int m=sofar.toLowerCase().charAt(k1)-48;
                    if(m==-16)
                        continue;
                    int i=k1;
                    while(true && i<sofar.length()-2){
                        if(sofar.charAt(i+1)==' ')
                            break;
                        else if(sofar.charAt(i+1)==sofar.charAt(k1)){
                            i++;
                        }else{
                            break;
                        }
    
                    }
                    i=i-k1;
                    //System.out.print(" " + m +", " + i + " ");
                    System.out.print(mappings[m][i%3]);
                    k1=k1+i;
                }
                System.out.println();
    
                return null;
            }
            int num= phone.charAt(j);
            int k=0;
            for(int i=j+1;i<phone.length();i++){
                if(phone.charAt(i)==num){
                    k++;
                }
            }
    
            if(k!=0){
    
                int p=0;
                ArrayList<String> list2= generateAllnums(phone.substring(p+1), sofar+phone.charAt(p)+ " ", 0);
                ArrayList<String> list3= generateAllnums(phone.substring(p+1), sofar+phone.charAt(p), 0);
    
            }
            else{
                ArrayList<String> list1= generateAllnums(phone.substring(1), sofar+phone.charAt(0), 0);
            }
            return null;
    
        }
    
    }
    
    0 讨论(0)
  • 2020-12-22 18:47

    In Java using recursion:

    import java.util.LinkedList;
    import java.util.List;
    
    public class Main {  
        // Number-to-letter mappings in order from zero to nine
        public static String mappings[][] = {
            {"0"}, {"1"}, {"A", "B", "C"}, {"D", "E", "F"}, {"G", "H", "I"},
            {"J", "K", "L"}, {"M", "N", "O"}, {"P", "Q", "R", "S"}, 
            {"T", "U", "V"}, {"W", "X", "Y", "Z"}
        };
    
        public static void generateCombosHelper(List<String> combos, 
                String prefix, String remaining) {
            // The current digit we are working with
            int digit = Integer.parseInt(remaining.substring(0, 1));
    
            if (remaining.length() == 1) {
                // We have reached the last digit in the phone number, so add 
                // all possible prefix-digit combinations to the list
                for (int i = 0; i < mappings[digit].length; i++) {
                    combos.add(prefix + mappings[digit][i]);
                }
            } else {
                // Recursively call this method with each possible new 
                // prefix and the remaining part of the phone number.
                for (int i = 0; i < mappings[digit].length; i++) {
                    generateCombosHelper(combos, prefix + mappings[digit][i], 
                            remaining.substring(1));
                }
            }
        }
    
        public static List<String> generateCombos(String phoneNumber) {
            // This will hold the final list of combinations
            List<String> combos = new LinkedList<String>();
    
            // Call the helper method with an empty prefix and the entire 
            // phone number as the remaining part.
            generateCombosHelper(combos, "", phoneNumber);
    
            return combos;
        }
    
        public static void main(String[] args) {
            String phone = "3456789";
            List<String> combos = generateCombos(phone);
    
            for (String s : combos) {
                System.out.println(s);
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-22 18:48

    This is the C# port of this answer.

    Code

    public class LetterCombinations
    {
        private static readonly Dictionary<string, string> Representations = new Dictionary<string, string>
        {
           {"2", "abc" },
           {"3", "def" },
           {"4", "ghi" },
           {"5", "jkl" },
           {"6", "mno" },
           {"7", "pqrs" },
           {"8", "tuv" },
           {"9", "wxyz" },
        };
    
        public static List<string> FromPhoneNumber(string phoneNumber)
        {
            var result = new List<string> { string.Empty };
    
            // go through each number in the phone
            for (int i = 0; i < phoneNumber.Length; i++)
            {
                var pre = new List<string>();
                foreach (var str in result)
                {
                    var letters = Representations[phoneNumber[i].ToString()];
                    // go through each representation of the number
                    for (int j = 0; j < letters.Length; j++)
                    {
                        pre.Add(str + letters[j]);
                    }
                }
                result = pre;
            }
    
            return result;
        }
    }
    

    Unit Tests

    public class UnitTest
    {
        [TestMethod]
        public void One_Digit_Yields_Three_Representations()
        {
            var sut = "2";
    
            var expected = new List<string>{ "a", "b", "c" };
            var actualResults = LetterCombinations.FromPhoneNumber(sut);
    
            CollectionAssert.AreEqual(expected, actualResults);
        }
    
        [TestMethod]
        public void Two_Digits_Yield_Nine_Representations()
        {
            var sut = "22";
    
            var expected = new List<string> { "aa", "ab", "ac", "ba", "bb", "bc", "ca", "cb", "cc" };
            var actualResults = LetterCombinations.FromPhoneNumber(sut);
    
            CollectionAssert.AreEqual(expected, actualResults);
        }
    
        [TestMethod]
        public void Three_Digits_Yield_ThirtyNine_Representations()
        {
            var sut = "222";
    
            var actualResults = LetterCombinations.FromPhoneNumber(sut);
    
            var possibleCombinations = Math.Pow(3,3); //27
    
            Assert.AreEqual(possibleCombinations, actualResults.Count);
        }
    }
    
    0 讨论(0)
  • 2020-12-22 18:50

    Here is one for pain C. This one is likley not efficet (in fact I don't think it is at all). But there are some intresting aspects to it.

    1. It take a number and converts it into a string
    2. It just raises the seed number once each time to create the next sequential string

    Whats nice about this is that there is no real limit to the size of the string (no character limit) This allows you to generate longer and longer strings if need be just by waiting.

    #include <stdlib.h>
    #include <stdio.h>
    
    #define CHARACTER_RANGE 95  //  The range of valid password characters
    #define CHARACTER_OFFSET 32 //  The offset of the first valid character
    
    void main(int argc, char *argv[], char *env[])
    {
        int i;
    
        long int string;
        long int worker;
        char *guess;    //  Current Generation
        guess = (char*)malloc(1);   //  Allocate it so free doesn't fail
    
        int cur;
    
        for ( string = 0; ; string++ )
        {
            worker = string;
    
            free(guess);
            guess = (char*)malloc((string/CHARACTER_RANGE+1)*sizeof(char)); //  Alocate for the number of characters we will need
    
            for ( i = 0; worker > 0 && i < string/CHARACTER_RANGE + 1; i++ )    //  Work out the string
            {
                cur = worker % CHARACTER_RANGE; //  Take off the last digit
                worker = (worker - cur) / CHARACTER_RANGE;  //  Advance the digits
                cur += CHARACTER_OFFSET;
    
                guess[i] = cur;
            }
            guess[i+1] = '\0';  //  NULL terminate our string
    
            printf("%s\t%d\n", guess, string);
        }
    }
    
    0 讨论(0)
  • 2020-12-22 18:50

    I am rather a newbie so please correct me wherever I am wrong.

    First thing is looking into space & time complexity. Which is really bad since it's factorial so for factorial(7) = 5040 any recursive algorithm would do. But for factorial(12) ~= 4 * 10^8 which can cause stack overflow in recursive solution.

    So I would not attempt a recursive algorithm. Looping solution is very straight forward using "Next Permutation".

    So I would create and array {0, 1, 2, 3, 4, 5} and generate all permutation and while printing replace them with respective characters eg. 0=A, 5=F

    Next Perm algorithm works as follows. eg Given 1,3,5,4 next permutation is 1,4,3,5

    Steps for finding next perm.

    1. From right to left, find first decreasing number. eg 3

    2. From left to right, find lowest number bigger than 3 eg. 4

    3. Swap these numbers as reverse the subset. 1,4,5,3 reverse subset 1,4,3,5

    Using Next permutation ( or rotation) you generate specific subset of permutations, say you want to show 1000 permutations starting from a particular phone number. This can save you from having all numbers in memory. If I store numbers as 4 byte integers, 10^9 bytes = 1 GB !.

    0 讨论(0)
  • 2020-12-22 18:51

    In C++(recursive):

    string pattern[] = {"0",".,!","ABC","DEF","GHI","JKL","MNO","PQRS","TUV","WXYZ"};
    ofstream keyout("keypad.txt");
    void print_keypad(char* str, int k, vector<char> patt, int i){
    if(str[k] != '\0')
    {
        int x = str[k] - '0';
        for(int l = 0; l < pattern[x].length(); l++)
        {
            patt[i] = pattern[x][l];
            print_keypad(str, k+1, patt, i+1);
        }
        keyout << endl;
    }
    else if(i == k)
    {
        string st(patt.data());
        keyout << st << endl;
        return;
    }
    }
    

    This function can be called with 'k' and 'i' equal to zero.

    Anyone, who requires more illustration to understand the logic, can combine recursion technique with following output:

    ADG
    ADH
    ADI
    
    AEG
    AEH
    AEI
    
    AFG
    AFH
    AFI
    
    
    BDG
    BDH
    BDI
    
    BEG
    BEH
    BEI
    
    BFG
    BFH
    ...
    
    0 讨论(0)
提交回复
热议问题