将数字编码为单词

时间:2015-03-14 19:19:40

标签: java algorithm

我的任务是编写一个程序,找到给定的电话号码 可能的文字编码并打印出来。 这是我从字母到数字的映射:

E | J N Q | R W X | D S Y | F T | A M | C I V | B K U | L O P | G H Z
e | j n q | r w x | d s y | f t | a m | c i v | b k u | l o p | g h z
0 |   1   |   2   |   3   |  4  |  5  |   6   |   7   |   8   |   9

我还有包含所有可能单词的dictionary.txt文件。 因此,如果我的程序输入数字562482作为输入,那么输出将是:

562482: mir Tor

因为我在我的dictionary.txt字词' mir'和' Tor'。

首先,我决定创建一个特殊的结构来快速搜索字典中的单词并使用它:

Map<String, List<String>> bucketedWords = new HashMap<>()

其中key是字典中每个单词的编号,value是带有这样编号的字典中所有单词的列表。在启动程序后初始化此结构。 条目示例:

key: 562 values: [mir, mix]

所以我可以在字典中快速搜索并按数字接收所有可能的单词。

现在我对第二部分感到好奇。 每个输入数字具有2 ^(n-1)个连续子串的组合。 我将输入数字拆分为这样的组合列表,并检查我的bucketWord字典中的每个条目。 如果输入数字的长度变长,那么我花了很多时间寻找子串的所有组合。这是解决此类问题的正确方法,还是有更好的解决方案?

有关任务here

的更多信息

修改

SpiderPig告诉我,我已经使用了递归但是变化很小,这有助于我找到后续数字的单词:

private List<List<String>> _findEncodings(String number, int startAt, boolean isNumber) {
    LinkedList<List<String>> result = new LinkedList<>();

    if (startAt == number.length()) {
        result.add(new LinkedList<String>());
        return result;
    }
    for (int endAt = startAt + 1; endAt <= number.length(); endAt++) {
        List<String> words = bucketedWords.get(number.substring(startAt,
                endAt));
        if (words != null) {
            List<List<String>> encodings = null;
            if((endAt - startAt == 1) && (words.size() == 1) && (isNumeric(words.get(0)))){
                if(isNumber){
                    continue;
                }
                encodings = _findEncodings(number, endAt, true);
            }else{
                encodings = _findEncodings(number, endAt, false);
            }
            for (String word : words) {
                for (List<String> encoding : encodings) {
                    List<String> enc = new LinkedList<>(encoding);
                    enc.add(0, word);
                    result.add(enc);
                }
            }
        }
    }
    return result;
}

public List<List<String>> findEncodings(String number) {
    return _findEncodings(number, 0, false);
}

public boolean isNumeric(String str)  
{  
  try  
  {  
    Double.parseDouble(str);  
  }  
  catch(NumberFormatException nfe)  
  {  
    return false;  
  }  
  return true;  
}

此外,我还在我的水桶中添加了数字。那是我的工作。

1 个答案:

答案 0 :(得分:2)

您应该使用trie而不是Map。 Trie一次一个地理解数字序列。 https://en.wikipedia.org/wiki/Trie

在这种情况下,它是O(max(len(word)))对于电话号码是O(7)~O(1)