这些回答大多效率低下,或者只能给出单词解决方案(没有空格)。
我的解决方案可以处理任意数量的单词,并且非常高效。
你需要使用 trie 数据结构。这里有一个完整的 Python 实现。你只需要将单词列表保存在名为 words.txt
的文件中。你可以在这里尝试 Scrabble 字典单词列表:
http://www.isc.ro/lists/twl06.zip
MIN_WORD_SIZE = 4
class Node(object):
def __init__(self, letter='', final=False, depth=0):
self.letter = letter
self.final = final
self.depth = depth
self.children = {}
def add(self, letters):
node = self
for index, letter in enumerate(letters):
if letter not in node.children:
node.children[letter] = Node(letter, index==len(letters)-1, index+1)
node = node.children[letter]
def anagram(self, letters):
tiles = {}
for letter in letters:
tiles[letter] = tiles.get(letter, 0) + 1
min_length = len(letters)
return self._anagram(tiles, [], self, min_length)
def _anagram(self, tiles, path, root, min_length):
if self.final and self.depth >= MIN_WORD_SIZE:
word = ''.join(path)
length = len(word.replace(' ', ''))
if length >= min_length:
yield word
path.append(' ')
for word in root._anagram(tiles, path, root, min_length):
yield word
path.pop()
for letter, node in self.children.iteritems():
count = tiles.get(letter, 0)
if count == 0:
continue
tiles[letter] = count - 1
path.append(letter)
for word in node._anagram(tiles, path, root, min_length):
yield word
path.pop()
tiles[letter] = count
def load_dictionary(path):
result = Node()
for line in open(path, 'r'):
word = line.strip().lower()
result.add(word)
return result
def main():
print 'Loading word list.'
words = load_dictionary('words.txt')
while True:
letters = raw_input('Enter letters: ')
letters = letters.lower()
letters = letters.replace(' ', '')
if not letters:
break
count = 0
for word in words.anagram(letters):
print word
count += 1
print '%d results.' % count
if __name__ == '__main__':
main()
程序运行时,单词将被加载到内存中的Trie数据结构中。之后,只需输入您想要查找的字母,它就会打印结果。它只会显示使用所有输入字母的结果,不会显示长度较短的结果。
为了减少输出结果的数量,程序会过滤掉短单词。您可以自由调整“MIN_WORD_SIZE”的设置。请记住,如果“MIN_WORD_SIZE”为1,则仅使用“astronomers”作为输入就有233,549个结果。也许您可以找到一个更短的单词列表,其中只包含常见的英语单词。
另外,缩写"I'm"(来自您的示例之一)除非您将"im"添加到字典并将“MIN_WORD_SIZE”设置为2,否则不会出现在结果中。
获取多个单词的技巧是:每当在搜索中遇到完整的单词时,请跳回到Trie数据结构的根节点。然后,继续遍历Trie直到所有字母都被使用。