我正在用python 2.7创建一个anagram解算器。
解算器获取用户输入的anagram,将每个字母转换为列表项,然后对照".txt"文件的行检查列表项,将匹配anagram字母的任何单词追加到possible_words列表中,准备打印。
它起作用了…几乎!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18# Anagram_Solver.py
anagram = list(raw_input("Enter an Anagram:").lower())
possible_words = []
with file('wordsEn.txt', 'r') as f:
for line in f:
if all(x in line + '
' for x in anagram) and len(line) == len(anagram) + 1:
line = line.strip()
possible_words.append(line)
print"
".join(possible_words)
对于没有重复字母的变位词,它工作得很好,但对于"hello"等单词,输出包含"helio、whole、holes"等单词,因为解算器似乎不将字母"l"计算为两个单独的条目?
我做错什么了?我觉得有一个简单的解决方案我错过了?
谢谢!
你的算法太简单了。与其检查anagram中的每个字符都在line中(这不足以识别一个变位词),还不如检查两个字符串中每种字符的计数是否相同。
问题出在all(x in line + '
' for x in anagram)上。如果单词中有一个"l",而在变位词中有100个,它仍然会返回True。
可能需要查看stackoverflow.com/questions/39028548/…,了解一些想法…(实际上是同一个问题)
@ev.kounis,谢谢你的提醒。我对python还比较陌生,认为我误解了all()函数的应用程序。我主要是粗暴地强迫这句话,直到我让它开始工作,我想我没有完全理解它是如何工作的。如果它不超出这个问题的范围,你能准确地解释它的作用吗?
取变位词(for x in anagram中的每一个字母)并检查它是否存在于该行(x in line中)。all(x,y,z, ..)与x and y and z and ...相同,因此anagram中的所有字母也必须存在于该行中,但该行不能包含更多的em(len(line) == len(anagram))。另外,请以不同的方式处理换行符。里面没有任何地方xd
@Ev.Kounis注意到了!;)非常感谢!:)
试着对这两个词进行排序,然后检查它们是否相等。
这可能是使用collections.Counter最容易解决的问题。
1
2
3
4
5>>> from collections import Counter
>>> Counter('Hello') == Counter('loleH')
True
>>> Counter('Hello') == Counter('loleHl')
False
Counter将检查字母和每个字母出现的次数是否相同。
或者只是sorted('Hello') == sorted('loleHl')作为这个答案:stackoverflow.com/questions/14990725/…
感谢您的回复@mgilson,我以前没有听说过counter类,但它看起来是一个有用的方法!
我选择的另一个答案是正确的,因为它会更详细一些,我觉得这很有帮助,但是看到计数器模块的不同控制台输出是很有用的。另外,感谢@chris_rands的回复,似乎排序方法的运行速度比使用集合快得多,所以我编辑了另一个答案来包含它。
您的代码按预期执行。实际上,你还没有让它检查一个字母是否出现两次(或3次以上),它只是检查了两次if 'l' in word,对于所有至少有一个l的单词来说,这总是正确的。
一种方法是计算每个单词的字母。如果字母数相等,则为变位词。这可以通过集合轻松实现。计数器类:
1
2
3
4
5
6
7
8
9
10
11from collections import Counter
anagram = raw_input("Enter an Anagram:").lower()
with file('wordsEn.txt', 'r') as f:
for line in f:
line = line.strip()
if Counter(anagram) == Counter(line):
possible_words.append(line)
print"
".join(possible_words)
另一种方法是使用sorted()函数,正如Chris在另一个答案的注释中建议的那样。这会按照字母顺序对变位词和行中的字母进行排序,然后检查它们是否匹配。此过程比Collections方法运行得更快。
1
2
3
4
5
6
7
8
9
10anagram = raw_input("Enter an Anagram:").lower()
with file('wordsEn.txt', 'r') as f:
for line in f:
line = line.strip()
if sorted(anagram) == sorted(line):
possible_words.append(line)
print"
".join(possible_words)
感谢您对我的代码进行深入的解释和重新编写。我测试了上面评论中的counter方法和chris_rands sorted方法,发现排序方法实际上处理得更快,所以我将把它附加到这个答案中并标记为正确。再次感谢!