问题描述
|
我正在尝试编写a子手算法。我的想法是这样的:
对字典进行预处理,该字典根据词的长度包含词的相对字母频率。步骤完成。
例:
#Each key corresponds to length of the word.
frequencyDict = {2: [\'a\',\'o\',\'e\',\'i\',\'m\',\'h\',\'n\',\'u\',\'s\',\'t\',\'y\',\'b\',\'d\',\'l\',\'p\',\'x\',\'f\',\'r\',\'w\',\'g\',\'k\',\'j\'],3: [\'a\',\'c\',\'v\',\'j\',\'z\',\'q\'],4: [\'e\',\'a\',5: [\'s\',6: [\'e\',7: [\'e\',8: [\'e\',\'q\',\'j\']}
我在词典中也有单词生成器:
dictionary = word_reader(\'C:\\\\Python27\\\\dictionary.txt\',len(letters))
基于此功能
#Strips dictionary of words that are too big or too small from the list
def word_reader(filename,L):
L2 = L+2
return (word.strip() for word in open(filename) \\
if len(word) < L2 and len(word) > 2)
这个特定的游戏将免费为您提供最后的元音。例如,如果这个单词是泥土的,
用户将获得以下面板:e ---- e-进行猜测。因此,我想找到一种创建新生成器或列表的方法
删除所有不符合e ---- e-模板的单词。
p = re.compile(\'^e\\D\\D\\D\\De\\D$\',re.IGnorECASE)
可以做到,但可能会找到单词
除了第一个字母和倒数第二个字母之外,其他地方还包含\'e \'的字符。
所以我的第一个问题是:
如何确保\'e \'为
仅位于第一和第二
倒数第二个位置
我如何创建一个智能功能,随着拼图的更新和计算机不断进行猜测,它将具有新的正则表达式?
例如,如果单词是monkey,则计算机将被赋予---- e-
第一步是从字典中删除所有不是6个字母的单词,以及所有不完全符合\'---- e- \'模板的单词,并将其放入newList中。怎么做
我要去做吗?
然后,它根据其中单词的相对频率来计算一个NEW frequencyDict
newList。
我当前执行此操作的方法如下所示:
cnt = Counter()
for words in dictionary:
for letters in words:
cnt[letters]+=1
这是最有效的方法吗?
然后,它将使用newfrequencyDict猜测最常见的字母,前提是它具有
还没有被猜到。它将继续执行此操作,直到(希望)猜出单词为止。
这是一种有效的算法吗?有更好的实现方式吗?
解决方法
关于正则表达式没有什么特别神奇的,并且将它们与您的整个字典进行匹配仍然需要O(n)的时间。我建议编写自己的函数来确定单词是否与模板匹配,并在整个过程中运行字典。
这是一个示例函数:
def matches_template(word,template):
found_chars = set(x for x in template if x != \'-\')
for char,template_char in zip(word,template):
if template_char == \'-\':
if char in found_chars: return False
else:
if template_char != char: return False
return True
至于确定要猜测的下一个字符,您可能不想选择最频繁的字符。相反,您想选择50%的单词中最接近的字符,这意味着您会以两种方式消除大多数可能性。即使这样也不是最佳选择-可能是某些字符在单词中出现两次的可能性更高,因此消除了更大比例的候选词-但这距离更近了。
, 这是很多问题。我会尝试回答一些。
您的正则表达式应该更像这样:\'^e[^e][^e][^e][^e]e[^e]$
\'。那些[^e]
位表示\“匹配不是\'e \'的任何字符。请注意,与您的正则表达式不同,它将处理非字母字符,但是如果您确保字典中只有字母,那么这应该不是问题请注意,一旦您发现了多个字母,就可以将所有字母放入每个“不匹配”部分中,例如,假设您猜到了“ a”,的\“ ea --- e- \”,现在您将与正则表达式\'^ea[^ae][^ae][^ae]e[^ae]$
\'匹配。
您可以简单地编写一个函数,该函数采用一个字符串,例如\“ ea --- e- \”并从中构建一个正则表达式。它只需要a)找到字符串中的所有非连字符,作为一个集合(在这种情况下为{\'a\',\'e\'}
),b)将集合展平为一个“ match-all-but-this \”正则表达式片段([^ae]
)-请注意顺序并不重要,这就是为什么我使用一组的原因,c)用连字符(ea[^ae][^ae][^ae]e[^ae]
)中的一个代替每个连字符,d)最后在前面加上\'^
\'并\最后是“$
\”。
最后是频率指令-那么这是一个非常独立的问题。很难比整个字典中的线性搜索都高效。我的一个建议是,您可能不应该多次数字母。例如,您是否想让单词“ earthen \”对“ e”的字母数贡献2分?我想在Hangman中只想让它计数一次,因为单词“ eeeeeeee”和单词“ the”对于猜测字母“ e”(成功)都具有相同的结果。但是我可能是错的。