我正在编写一个游戏,当给出一个部分填充的单词时,搜索字典并返回所有匹配的单词。为此,我试图找到一种可用于上述目的的算法。例如,给定 - - a - ,算法将在字典中搜索长度为4且“a”为第三个字母的所有单词。
是否有这样的算法?如果没有,有人可以大致了解如何设计这样的算法吗?
先谢谢。
答案 0 :(得分:3)
嗯,它还不存在,但已经对SO进行了研究,以解决填字游戏问题。
我提出的解决方案的要点是按字母和索引编制索引,这是Python给出的:
class Index:
def __init__(self, list):
self.data = defaultdict(set)
for word in list: self.add(word)
def add(self, word):
for l in range(0, len(word)):
self.data[(l, word[l])].insert(word)
def look(self, letters):
"""letters is a list of tuples (position, letter)"""
result = None
for (p,l) in letters:
set = self.data[(p,l)]
if result == None: result = set
else: result = result.insersection(set)
return result
这个想法很简单:你有一个大索引,每个夫妻都有一组单词(position,letter)
。在你的情况下,它可以扩展为每个单词长度有一个索引,这将减少单词集的大小,从而更快。
对于检索,您只需将所有集合相交以具有与所有已知字母匹配的公共单词集。
答案 1 :(得分:1)
另一个解决方案可能是将您的字典构建为prefix tree。那么你的算法就必须通过那棵树。对于每个节点,您知道哪个字母关联以及单词中的位置,以便您知道它是否与您要查找的字母匹配。如果不是你停下来,不要经过它的孩子。您还可以了解何时查看查询的长度。您到达的每个叶子都可以添加到结果列表中。
就内存消耗而言,此解决方案可能非常有效。
答案 2 :(得分:0)
test = '--a-';
for each (words as word)
{
if ((word.length == test.length)
&& (test.index(0) == '-' || (word.index(0) == test.index(0)))
&& (test.index(1) == '-' || (word.index(1) == test.index(1)))
&& (test.index(2) == '-' || (word.index(2) == test.index(2)))
&& (test.index(3) == '-' || (word.index(3) == test.index(3))))
{
// match
}
}
这就是你需要的吗?显然它需要修改一点才能工作不同的长度。
答案 3 :(得分:0)
据我所知,您不能使用正则表达式查询吗?在上面的示例中,模式类似于??a?
然后你需要遍历所有单词并检查是否匹配。
答案 4 :(得分:0)
如果你在功能相当强大的计算机上运行(与负载相比),那么PierrOz有一个很好的答案:将字典存储为前缀树。然后你可以进行广度优先搜索,只有达到你真正知道这封信的水平才能修剪。
如果您需要更快的解决方案,则需要一种限制搜索深度的方法。一种可能性是将答案分开。例如,您可以通过按长度对单词进行分组来开始;那么你只需查看一定长度的单词列表。然后你可以通过包含特定字母的单词进行子组 - 所有字母对都可能就足够了。这将为您提供一个类似于13000个元素的数组,您可以快速索引:计算单词中的字母数,然后在单词中选择最稀有的字母或两个字母,并使用它来索引到只有迷你前缀树用这些字母持有那个长度的单词。在大多数情况下,这种策略应该可以让你减少到每个bin几百个单词,即使你选择了树的大部分宽度,前缀树搜索也应该很快。