Как напечатать ассоциацию строк с номера телефона в виде текста? - PullRequest
1 голос
/ 07 декабря 2009

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

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

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

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

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

Ответы [ 8 ]

2 голосов
/ 07 декабря 2009

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

pad [7] выдаст массив {'p', 'q', 'r'},

pad [6] выдаст массив {'m', 'n', 'o'},

pad [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 голосов
/ 02 октября 2015
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 голосов
/ 29 апреля 2014

Я давал сегодня интервью и задавал этот вопрос. Я боролся во время интервью, но после этого я попробовал и все-таки реализовал. Вот решение в 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");
    }
};
0 голосов
/ 25 февраля 2013

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

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

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

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 голосов
/ 07 декабря 2009

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

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

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

0 голосов
/ 07 декабря 2009

На основе 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 было обновлено при выполнении предыдущего вызова, поэтому при выполнении следующей итерации цикла for он ищет другое число, чем в pad. Вместо того чтобы увеличивать его в вызове, мы просто передаем следующее значение.
  • Для поиска персонажей в массиве пэдов использовалась позиция в номере вместо номера в этой позиции. Например. если бы число было просто 233, оно давало 01a, 01b, 01c вместо add, ade ...
  • if (i<num.length-1) был неправ. Мы хотим рекурсивно вызывать один раз для каждой цифры в номере так: if (next < num.length-1)
  • Изменено stringify(alpha) на String.valueOf(alpha)
0 голосов
/ 07 декабря 2009

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

// 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», основная функция printAllPossabilities вызовет recursivePrintAllPossabilities с prefix = "" и 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», и так далее. К тому времени, когда контроль вернется к исходной функции, он напечатает все возможности.

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

0 голосов
/ 07 декабря 2009

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

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

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

редактирование: Более элегантный подход состоит в том, чтобы посмотреть, сколько у вас 4 (давайте назовем это x) символьных цифр и 3 (назовем это один y) цифр, и считать от 0 до 4 ^ x * 3 ^ y-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".

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...