2009-12-07 3 views
1

Мне нужна помощь с методом, который я пишу для проекта. метод изменяет телефонный номер на список текстовых строк.Как печатать ассоциацию строк с номера телефона в виде текста?

Вы знаете, что у 2-9 есть письма, связанные с ними на телефоне. я хотел бы сделать конвертер, который изменит 7-значное число на список строк. я бы хотел увидеть все возможности. Я уже вырезал все 1 и 0, так как у них нет писем к ним. Пример: если наш номер был всего лишь двумя цифрами, 37 будет:

DP DQ DR DS EP EQ ER ES FP FQ FR FS.

До сих пор я пытался использовать вложенные для циклов, но я не получаю правильные выходы. любая помощь или идеи были бы хороши. благодаря

(им не просить полный код, но больше как предложения о том, как это сделать)

+2

Показать код, который вы пытаетесь. –

+0

Это будет много комбинаций для обычного номера телефона. – Thilo

+0

Не имеет значения с точки зрения попытки ответить на ваш вопрос, но сколько телефонных номеров мы говорим здесь? – Buhb

ответ

0

Если я правильно помню, есть не более 4 букв для любой цифры.

Грубый способ генерации состоит в том, чтобы подсчитать от 0 до 4^(количество цифр) -1 в базе 4, что даст вам цифры, такие как 02031, пусть 0 представляет первую букву для соответствующей цифры, 1 для второго и так далее. Все номера, содержащие 3 в позиции, имеющей цифру, которая имеет только 3 буквы, отбрасываются.

10-значное число даст список из более чем миллиона базовых 4 чисел. Вы были предупреждены.

Редактировать: Более элегантный подход состоит в том, чтобы посмотреть, сколько цифр (назовем его х) символами и 3 (назовем это один у) знаками символов, которые у вас есть, и считайте от 0 до 4^х * 3^у-1. каждый номер может быть переведен в последовательность чисел, как указано выше, с использованием операторов/и%.

пример: если 8 и 9 являются 4 символов цифр, и вы хотите получить список строковых представлений числа 258, то считать от 0 до 3^2 * 4-1 = 35. принимая число 21 , например: Работа свой путь в обратном направлении, крайний правый символ (от 8), вы получите характер, принимая

21% 4 = 1, 1, представляющий «T»

Деление прочь информацию из этого характер вы делаете 21/4 = 5.

Следующий символ:

5% 3 = 2, 2, представляющий 'L'

5/3 = 1.

Окончательный характер:

1% 3 = 1, представляющий 'B'

В этом вы получите строку «blt».

Существует некоторый порядок хранения этого алгоритма, но вы не получаете накладные расходы и отбрасываете из приведенного выше примера, и вы не получаете накладных расходов памяти, которые имеют рекурсивные алгоритмы.

0

Возможно, вы захотите использовать рекурсию.Вы сказали, что не даст вам код, так вот только наброски:

// This is the function you're writing. It prints every possible 
// string you can make with the digits of that phone number by 
// calling another function recursively. 
void printAllPossibilities(String phoneNumber) { 
    recursivePrintAllPossibilities("", phoneNumber); 
} 

void recursivePrintAllPossibilities(String prefix, String phoneNumber) { 
    // 1. If the phone number is empty, just print the prefix and return. 
    // 2. If the phone number is not empty, take the first digit and convert it 
    // into possible letters. For each letter, add that letter to the prefix 
    // and then call recursivePrintAllPossibilities with the new prefix, and 
    // with the now-truncated phone number. 
} 

Учитывая ваш пример вход «37», основные функции printAllPossibilities будем называть recursivePrintAllPossibilities с префиксом = «» и PHONENUMBER = «37». Эта функция будет называть себя три раза:

  1. После того, как с префиксом = "D" и PHONENUMBER = "7"
  2. После того, как с префиксом = "E" и PHONENUMBER = "7"
  3. После с префиксом = "F" и PHONENUMBER = "7"

Первый из этих вызовов будет называть себя снова в четыре раза:

  1. После того, как с префиксом = "DP" и PHONENUMBER = ""
  2. После с префиксом = "DQ" и PHONENUMBER = ""
  3. После того, как с префиксом = "DR" и PHONENUMBER = ""
  4. После того, как с префиксом = "DS" и PHONENUMBER = ""

Каждый из этих вызовов будет просто печатать префикс. Затем управление возвращает один уровень и выполняет все выходы, начинающиеся с «E», и так далее. К тому времени, когда элемент управления будет возвращен исходной функции, он будет распечатывать каждую возможность.

Практика, чтобы научиться «думать» рекурсивно, но со временем это станет второй натурой.

2

Ключом к вашему решению является использование массива пэдов, объявленного в приведенном ниже коде. В частичной телефонный номер 763, например,

колодки [7] даст массив { 'р', 'Q', 'г'},

колодки [6] даст массив { 'м', 'N', 'о'},

колодки [3] даст массив { 'A', 'B', 'C'},

Затем, используя рекурсивный метод getAlpha (int [] num, int next, char [] alpha), чтобы перебирать каждую возможность комбинации, формируя алгоритмическое дерево алфавитных прогрессий. В каждом листовом/конечном узле дерева есть заполненный массив алфавитов, которые должны быть добавлены в список. Использование только одного массива алфавитов для повторного использования/перезаписывания, когда он возвращается назад к предыдущей позиции цифр, возможно, потому что строковый алфавитный массив добавляется только тогда, когда достигнут узел листа/конца. stringify (char []) не включен здесь.

getAlpha (int [] num) - это метод точки входа, начинающийся с позиции цифры 0 рекурсии. Каждый уровень рекурсии обрабатывает следующую цифру номера телефона.

public class Z{ 
    // 2D array [i][j] 
    // use phone digit as array index i 
    final char[][] pad = { 
    {'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'}, 
    }; 

    // This will be the horrendously long list of possible alphabetic codes 
    List<String> combinations = new ArrayList<String>(); 

    void getAlpha(int[] num, int next, char[]alpha){ 
    // iterate over all possible alphabets of next digit 
    for (int i=0; i<pad[next].length; i++){ 
     //set,overwrite next cell of array with iterated alphabet 
     alpha[next] = pad[next][i]; 
     if (i<num.length-1) 
     //process next next digit 
     getAlpha(num, next++, alpha); 
     else 
     //if end of number 
     //append array to horrendously long list 
     combinations.add(stringify(alpha)); 
    } 
    } 

    public void getAlpha(int[] num){ 
    getAlpha(num, 0, new char[num.length]); 
    } 
} 
+0

Я думаю, что это: 'for (int i = 0; i

+0

Был почти там, но я нашел еще несколько ошибок, так что опубликовал исправленную версию. –

0

Основано на h2g2java, но с исправленными ошибками, чтобы заставить его работать.

public class Z{ 
    // 2D array [i][j] 
    // use phone digit as array index i 
    final char[][] pad = { 
    {'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'}, 
    }; 

    // This will be the horrendously long list of possible alphabetic codes 
    List<String> combinations = new ArrayList<String>(); 

    void getAlpha(int[] num, int next, char[]alpha){ 
    // iterate over all possible alphabets of next digit 

    for (int i=0; i<pad[num[next]].length; i++){ 
     //set,overwrite next cell of array with iterated alphabet 
     alpha[next] = pad[num[next]][i]; 
     if (next<num.length-1) { 
     //process next next digit 
     getAlpha(num, next + 1, alpha); 
     } else { 
     //if end of number 
     //append array to horrendously long list 
     combinations.add(String.valueOf(alpha)); 
     } 
    } 
    } 

    public void getAlpha(int[] num){ 
    getAlpha(num, 0, new char[num.length]); 
    } 
} 
  • при возвращении из рекурсии next был обновлен при выполнении предыдущего вызова так при выполнении следующей итерации для цикла он смотрит вверх другой номер, чем это должно быть в pad. Вместо того, чтобы увеличивать его в вызове, мы просто передаем следующее значение.
  • Использовал позицию в номере вместо числа в этой позиции, чтобы найти кулаки в массиве пэдов. Например. если число было просто 233, оно давало 01a, 01b, 01c вместо add, ade ...
  • if (i<num.length-1) был не прав. Мы хотим, чтобы рекурсивно вызвать один раз для каждой цифры числа так его: if (next < num.length-1)
  • Изменено stringify(alpha) к String.valueOf(alpha)
0

Я предполагаю, что конечной целью этого является то, чтобы определить, какие из существующих слов соответствовать номеру, указанному по телефону (например, phonespell.org). Если это так, вы можете применить словарь, который вы будете использовать ранее в этом процессе, и избегать создания огромного списка бессмысленных слов. Так что в целом:

  • добавить все возможные буквы для первой цифры в список решений
  • для остальных цифр:
    • для каждого решения:
    • удалить раствор из списка раствора
    • для каждой возможной буквы для текущей цифры:
      • кандидат = решение + письмо
      • если есть слово из словаря, начиная с кандидатом, добавить кандидата в список решений

Вы можете optimze это путем копирования всех слов из словаря до сих пор соответствия своих решений в новый сниженном словарь между каждым итерация.

0

Это старая тема, но в любом случае ..

Рекурсивный решение действительно хорошо! Но хочу представить некоторую альтернативу, давайте назовем это «OOP решение» .. :) может быть, кто-то будет полезно ..

Вам просто нужно создать некоторый класс, способный отслеживать состояние представления значного в:

private class DigitInLetter { 
    private int digit; 
    private char[] letters; 
    private int currentLetterIndex; 

    private DigitInLetter(int digit) { 
     this.digit = digit; 
     this.letters = pad[digit];//the same pad from recursive solution.. 
     currentLetterIndex = 0; 
    } 

    /** 
    * Changes selected letter to the next one. If there is no more items 
    * in the array, changes it to one with index 0. 
    * 
    * @return true if index reset to 0, otherwise false. 
    */ 
    public boolean changeToNextLetter() { 
     if (currentLetterIndex < letters.length-1) { 
      currentLetterIndex++; 
      return false; 
     } else { 
      currentLetterIndex = 0; 
      return true; 
     } 
    } 

    public char getCurrentLetter() { 
     return letters[currentLetterIndex]; 
    } 
} 

При этом вы должны просто написать один цикл линии, чтобы создать массив DigitInLetter [], соответствующий заданному числу. И, используйте следующий простой код для перебора всех возможностей:

int digitIndex = 0; 
    while (digitIndex < digitInLetterArray.length) { 
     somewhere.add(digitInLetterArray.TO_STRING);//do here whatewer you want.. e.g. some simple toString can be written for DigitInLetter[]... just be careful to do not accumulate tons of references to the same objects being changed..)) 

     for (digitIndex = 0; digitIndex < digitInLetterArray.length && 
      digitInLetterArray[digitIndex].changeToNextLetter(); digitIndex++); 
    } 

еще несколько строк коды в классе моделирования, но довольно простой в результате ..

0

я давал интервью сегодня и спросил этот вопрос. Я боролся во время интервью, но после этого я попробовал и осуществил его. вот решение на Java.

public static List<String> deriveWordCombinations(String number){ 

    List<String> finalWord = new ArrayList<String>(); 
    List<String> iterative = new ArrayList<String>(); 
    finalWord.add(""); 
    for(int i=0;i<number.length();i++){ 
     char c = number.charAt(i); 
     String stringForNumber = map.get(c); 
     for(String s:finalWord){ 
      for(char cs: stringForNumber.toCharArray()){ 
       iterative.add(s+cs); 
      } 
     } 
     finalWord = iterative; 
     iterative = new ArrayList<String>(); 
    } 

    return finalWord; 
} 

static final HashMap<Character,String> map = new HashMap<Character,String>(){ 
    { 
    put('2',"abc"); 
    put('3',"def"); 
    put('4',"ghi"); 
    put('5',"jkl"); 
    put('6',"mno"); 
    put('7',"pqrs"); 
    put('8',"tuv"); 
    put('9',"wxyz"); 
    } 
}; 
-1
package LinkedList; 

import java.util.ArrayList; 
import java.util.LinkedHashMap; 

public class letterDigits { 

    private static LinkedHashMap<String, String> map; 

    private static ArrayList<String> deriveWordCombinations(String number) { 

     ArrayList<String> finalWord = new ArrayList<String>(); 
     ArrayList<String> iterative = new ArrayList<String>(); 
     finalWord.add(""); 

     for (int i = 0; i < number.length(); i++) { 
      String c = number.substring(i, i + 1); 

      String stringForNumber = map.get(c); 
      for (String s : finalWord) { 
       for (char cs : stringForNumber.toCharArray()) { 
        iterative.add(s + cs); 
       } 
      } 
      finalWord = iterative; 
      iterative = new ArrayList<String>(); 
      System.out.println("Final Word->" + finalWord); 
     } 

     return finalWord; 
    } 

    public void makeHashMap() { 
     map.put("1", ""); 
     map.put("2", "ABC"); 
     map.put("3", "DEF"); 
     map.put("4", "GHI"); 
     map.put("5", "JKL"); 
     map.put("6", "MNO"); 
     map.put("7", "PQRS"); 
     map.put("8", "TUV"); 
     map.put("9", "WXYZ"); 
    } 

    public static void main(String[] args) { 
     // TODO Auto-generated method stub 
     letterDigits obj = new letterDigits(); 
     map = new LinkedHashMap<String, String>(); 
     obj.makeHashMap(); 
     // System.out.println(map); 
     String str = "345"; 
     ArrayList<String> word = letterDigits.deriveWordCombinations(str); 
     System.out.println("Word->" + word); 

    } 
} 

Производит вывод:

Final Word->[D, E, F] 
Final Word->[DG, DH, DI, EG, EH, EI, FG, FH, FI] 
Final Word->[DGJ, DGK, DGL, DHJ, DHK, DHL, DIJ, DIK, DIL, EGJ, EGK, EGL, EHJ, EHK, EHL, EIJ, EIK, EIL, FGJ, FGK, FGL, FHJ, FHK, FHL, FIJ, FIK, FIL] 
Word->[DGJ, DGK, DGL, DHJ, DHK, DHL, DIJ, DIK, DIL, EGJ, EGK, EGL, EHJ, EHK, EHL, EIJ, EIK, EIL, FGJ, FGK, FGL, FHJ, FHK, FHL, FIJ, FIK, FIL] 

для ввода "345"

+0

Не могли бы вы дать некоторые подробности о том, что происходит в этом коде, пожалуйста? Кодовые ответы считаются низкими. –

Смежные вопросы