我在 Python 2.7 中编写了一个简短的 Anagram Solver 脚本。
#Import Permutations Module
from itertools import permutations as perm
#Defined Functions
def check(x,y):
#Opens Dictionary File
with open('wordsEn.txt') as dictionary:
'''Checks the permutations against all of the dictionary words and appends
any matching ones to on of the empty lists'''
for line in dictionary:
for i in x:
if i + '\n' == line:
y.append(i)
#Empty Lists that will be appended to later
anagram_perms = []
possible_words = []
#Anagram User Input
anagram = list(raw_input("Input scrambled word: ").lower())
#Creates single list items from the permutations, deletes duplicates
for char in perm(anagram):
anagram_perms.append("".join(char))
anagram_perms = list(set(anagram_perms))
#Uses the defined function
check(anagram_perms, possible_words)
#Prints the number of perms created, then prints the possible words beneath it
print len(anagram_perms)
print '\n'.join(possible_words)
它基本上需要用户输入anagram,生成并将所有可能的字母组合(使用itertools.permutations
)放入列表中,删除任何重复项。然后,它会根据一个100000字的词典文本文件检查这些组合中的每一个,将任何匹配的单词放入要打印的列表中。
我遇到的问题是,如果用户输入长度超过6个唯一字母的单词,则生成的排列数会导致挂起和崩溃。 9个字母的字谜将是典型的输入,但显然如果所有字母都不同,它们将输出 362880 (' 9!')排列,这是不可行的。
虽然我有几个潜在解决方案:
我对Python开发相当新,但并不知道这些是否可行,或者我将如何将它们应用到我的代码中;关于类似主题的其他问题实际上无法提供帮助。
如果有人希望看到我的代码到目前为止,我很乐意将其压缩并发布,但为了不再提出这个问题,我会将其删除,除非它&# 39; s要求。 (上面更新)
谢谢!
答案 0 :(得分:1)
它认为最好的解决方案可能是不使用排列。更有可能的是,大多数生成的排列都不是一个词 - 所以生成它们都是浪费。
您可以考虑将此词典预处理为已排序字母的字典,以及这些字母所包含的单词列表。然后,在对输入进行排序后,您的anagram解算器将在字典中进行简单查找。
首先,从单词列表中创建字典并保存到文件中:
from collections import defaultdict
import json
word_list = ['tab', 'bat', 'cat', 'rat', ...] # 100k words
word_dict = defaultdict(list)
for word in word_list:
word_dict[''.join(sorted(word))].append(word)
with open('word_dict.json') as f:
f.write(json.dumps(dict(word_dict)))
然后,在运行anagram代码时,加载字典并使用它来查找已排序的输入:
import json
empty_list = []
with open('word_dict.json', 'r') as f:
word_dict = json.loads(f.read())
while True:
anagram = raw_input('Enter in an anagram: ')
sorted_anagram = ''.join(sorted(anagram))
print word_dict.get(sorted_anagram, empty_list)
答案 1 :(得分:0)
这应该有所帮助。 itertools.permutations
函数返回一个迭代器。这意味着整个列表不存储在内存中;相反,你可以调用下一个值,它将计算动态需要的内容。
from itertools import permutations
with open('./wordlist.txt', 'r') as fp:
wordlist_str = fp.read()
wordlist = set(wordlist_str.lower().split('\n')) #use '\r\n' in Windows
def get_anagrams(word):
out = set()
for w in permutations(word.lower()):
if ''.join(w) in wordlist:
out.add(''.join(w))
return out