【发布时间】:2011-09-27 03:45:42
【问题描述】:
我正在制作一个移动应用程序来查找字谜和部分匹配项。移动设备很重要,因为计算能力不强,而效率是关键。
该算法采用任意数量的字母,包括重复字母,并找到由其字母组成的最长单词,每个字母仅使用一次。我也有兴趣快速找到最高的结果,只要满足 N,我并不真正关心底部(较短的)。例如:
STACK => stack, tacks, acts, cask, cast, cats…
我进行了一些谷歌搜索并找到了一些算法,我想出了一个我认为有效的算法,但没有我想要的那么有效。
我有一个预先制作的查找字典,它将排序的键映射到生成该键的真实单词。
"aelpp" => ["apple", "appel", "pepla"]
我已根据键的长度将每个字典进一步拆分为不同的字典。因此,5 个字母长的键在一个字典中,6 个键在另一个字典中。这些字典中的每一个都位于一个数组中,其中索引是在字典中找到的键的长度。
anagramArray[5] => dictionary5
dictionary5["aelpp"] => ["apple", "appel", "pepla"]
我的算法从输入单词“lappe”开始,然后对其进行排序:
"lappe" => "aelpp"
现在,对于每本最多包含 5 个字母的字典,我进行比较以将其提取出来。这是伪代码:
word = input.sort
for (i = word.length; i > 0; i--)
dictionaryN = array[i]
for (key in dictionaryN)
if word matches key
add to returnArray
end
end
if returnArray count > N
break
end
end
returnArray.sort by longest word, alphabetize
该词典中只有大约 170,000 个单词,但对于 12 个字母的输入,搜索最多需要 20 秒。我的match 方法从键中生成了一个正则表达式:
"ackst" => /a.*c.*k.*s.*t.*/
这样,例如,一个 4 个字母的键,如 acst(行为),将匹配 ackst(堆栈),因为:
"ackst" matches /a.*c.*s.*t.*/
我看到其他应用程序在更短的时间内做同样的事情,我想知道我的方法是垃圾还是需要一些调整。
如何获得最大的计算效率以从一个单词中生成前 N 个字谜,按最大长度排序?
【问题讨论】:
-
CodeReview 上的相关问题:codereview.stackexchange.com/questions/1690/…
-
我设计了一个漂亮的字典结构优化,使用记录数组而不是树,数组内的相对偏移量,以及一些位打包。如果您有兴趣,我可以详细说明。
-
我实际上用自己的方法解决了这个问题,并得到了 mcdowella 的提示。它非常快,不使用字典树,而是使用 dfs 搜索原始单词。我不想再优化了,但如果你写了一篇博文,我会读的。
标签: algorithm performance logic anagram