(免责声明:伪代码可能不是有效的java,即使它看起来像它)
听起来你有一堆乱七八糟的字母,想要找到所有可以用它们拼写的英文单词。
如果在对它们进行排序时它们比较相等,则两个字符串是彼此的字谜。排列候选词中的字母顺序以查看它们是否是合法的英语单词是昂贵的。相反,对字母进行排序并将其与您的单词列表进行比较:
boolean is_anagram(string word_a, string word_b){
return sorted(word_a).equals(sorted(word_b));
}
List<string> valid_anagrams(string candidate_word){
anagrams = new List<string>();
foreach(string word : list_of_words){
if (is_anagram(candidate, word)){
anagrams.push(word);
}
}
return anagrams;
}
如果您的单词列表中的单词数量小于候选单词大小的阶乘,这会更有效。例如,Words With Friends 中的合法词数约为 170,000,因此您更倾向于使用上述方法来检查长度为 9 或以上的词。
如果您打算检查大量候选词,那么您可以通过保存所有有效词的排序形式来节省时间。创建一个字典,其中键是已排序的字符串,值是英语单词列表,这些单词是该字符串的变位词。它应该如下所示:
{
"act": ["act", "cat", "tab"],
"abll": ["ball"],
"aeprs": ["asper", "parse", "pears", "reaps", "spare", "spear"]
}
您可以在程序开始时构建此字典一次,如下所示:
d = new Dictionary<string, List<string>>();
foreach (string word in list_of_words){
string key = sorted(word)
if (!d.contains_key(key)){
d[key] = new List<string>();
}
d[key].push(word);
}
然后为字符串找到有效的字谜只是访问字典的问题。
List<string> valid_anagrams(string candidate_word){
string key = sorted(candidate_word);
if (!d.contains_key(key)){
return new List<string>();
}
else{
return d[key];
}
}