我有一项任务。我试过搜索堆栈溢出。
我需要阅读一个充满电话号码的文本文件。这部分我知道该怎么做。
接下来,我需要根据以下编码将电话号码转换为所有可能的单词排列:
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
并根据我要阅读的字典文件检查它们。 (阅读部分我已经知道该怎么做了)
有人可以建议一个好的算法来编码电话号码和检查字典吗?
到目前为止我尝试的所有内容都抛出了OutOfMemory异常,并且赋值指定不一定是这种情况。
答案 0 :(得分:0)
这是:
static char[][] letters = {"Ee".toCharArray(), // 0
"JNQjnq".toCharArray(), // 1
"RWXrwx".toCharArray() // 2
//.... add remaining
};
static Set<String> words = new HashSet<>(Arrays.asList(
"Stack",
"Overflow",
"foo",
"bar"
//... add other words
));
// main method
public void generateAndCheckAll(String number) {
int[] num = new int[number.length()]; // store number as digits
int[] ind = new int[number.length()]; // store letter indices
int i = 0;
for (char c : number.toCharArray()) { // convert String to int array
num[i++] = c - '0';
}
do {
String word = generateWord(num, ind);
System.out.println(word + (words.contains(word) ? " is contained" : " is not contained"));
} while (next(num, ind));
}
// generate word by number array and index array
public String generateWord(int[] num, int[] ind) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < ind.length; i++)
sb.append(letters[num[i]][ind[i]]);
return sb.toString();
}
// switch index array to next
public boolean next(int[] num, int[] ind) {
int i = ind.length - 1;
while (i >= 0 && ind[i] == letters[num[i]].length - 1) // search for the index that can be incremented
i--;
if (i < 0)
return false;
ind[i]++; // increment such index
for (int j = i + 1; j < num.length; j++) // change remaining indices to 0
ind[j] = 0;
return true;
}
这里的主要思想是在每次迭代时存储字母索引数组,并根据它生成一个新单词。例如,对于数字201
和索引数组[0, 0, 5]
,将生成单词REq
:数字2
的第0个字母,数字{{1的第0个字母数字0
的第5个字母和第5个字母。
然后在字典中查找该单词,并将索引数组切换到下一个。从最后扫描我们搜索可以递增的索引(这样就不会溢出给定位置的数字的字母数):我们不能增加&#34; 5&#34; (因为数字1
只有6个字母),但我们可以增加&#34; 0&#34;。因此,索引数组更改为1
,并且一次又一次地重复所有索引,直到所有索引都被允许为最大值。
要了解它的工作原理,请按步骤模式调试此代码。它很容易理解,并将相同的想法应用于许多其他类似的任务。
顺便说一下,这不是最有效的方法,因为字典大小(我认为10-100K)很可能小于组合计数(对于10位数字,大约为60M)。如果您真的不需要生成所有组合,您可以执行字典准备:
为词典中的每个单词生成一个数字,
将每个生成的数字映射到相应的单词(单词),并在哈希集合中收集这些映射。
然后,对于您收到的号码,您只需查看给定号码是否存在单词(单词)。这种方法需要较长的准备阶段和更大的空间,但查找速度显着提高。