これらの答えのほとんどはひどく非効率的であり、および/または一言の解決策しか与えません(スペースなし)。私のソリューションは任意の数の単語を処理し、非常に効率的です。
必要なのはトライデータ構造です。これが完全なPython実装です。必要なのは、という名前のファイルに保存された単語リストだけですwords.txt
。ここでスクラブル辞書の単語リストを試すことができます。
http://www.isc.ro/lists/twl06.zip
MIN_WORD_SIZE = 4 # min size of a word in the output
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()
プログラムを実行すると、単語がメモリ内のトライにロードされます。その後、検索したい文字を入力するだけで、結果が出力されます。すべての入力文字を使用した結果のみが表示され、それより短いものは表示されません。
出力から短い単語をフィルタリングします。そうでない場合、結果の数は膨大になります。設定を自由に調整してMIN_WORD_SIZE
ください。が1の場合、入力として「天文学者」を使用するだけで233,549の結果が得られることに注意してMIN_WORD_SIZE
ください。おそらく、より一般的な英語の単語のみを含む短い単語リストを見つけることができます。
また、辞書に「im」を追加MIN_WORD_SIZE
して2に設定しない限り、短縮形「I'm」(例の1つから)は結果に表示されません。
複数の単語を取得する秘訣は、検索で完全な単語に遭遇するたびに、トライのルートノードに戻ることです。次に、すべての文字が使用されるまで、トライをトラバースし続けます。