因此,给定两个字符串的输入,我有以下线性时间解决方案来检查一个字符串是否是另一个的字谜。我想要一个更简洁和pythonic的线性时间解决方案。
def perm_check(str1,str2):
if len(str1)!=len(str2):
return False
d1,d2={},{}
for i in range(len(str1)):
l1=str1[i]
l2=str2[i]
if l1 in d1:
d1[l1]+=1
else:
d1[l1]=1
if l2 in d2:
d2[l2]+=1
else:
d2[l2]=1
for letter in d1:
if letter not in d2:
return False
if d1[letter] != d2[letter]:
return False
return True
print(perm_check("stab","bats"))
如何优化此功能?
答案 0 :(得分:3)
您可以使用python collections.Counter
类来执行此操作。基本上,在字谜中,每个字符的数量在两个字符串之间必须相同,因此您需要的只是两个字符串中每个字符的字符数,并进行比较。 Counter
课程将为您创建词典,您可以直接比较。
from collections import Counter
def is_anagram(string1, string2):
return Counter(string1) == Counter(string2)
结果:
>>> is_anagram("helper", "perhel")
True
>>> is_anagram("helper", "perhe")
False
>>> is_anagram("helper", "perhes")
False
答案 1 :(得分:2)
使用已排序:
>>> def anagram(str1,str2):
... return sorted(str1) == sorted(str2)
...
>>> anagram('hello','ellho')
True
>>> anagram('abcd','cabd')
True
>>> anagram('hello','hellohe')
False
答案 2 :(得分:1)
您可以使用其他答案中提到的任一计数器,或字典来浏览元素并计算每个字符的频率。
您可以使用zip
遍历两个列表,方法是将元素放在相同的位置(只是为了加速因为它们具有相同的长度)。如果密钥存在,我们添加一个。如果它不存在,我们将键添加到字典中,值为1
def perm_check(str1,str2):
if len(str1)!=len(str2):
return False
d1,d2={},{}
for x,y in zip(list(str1),list(str2)):
if x not in d1.keys():
d1[x]=1
else:
d1[x]+=1
if y not in d2.keys():
d2[y]=1
else:
d2[y]+=1
return d1==d2
print perm_check("dad","add") #True
print perm_check("dad","adb") #False
答案 3 :(得分:0)
potential = ["ice", "cei", "cheese", "pool", "loop", "oolp", "eseehc"]
sets = []
setCount = {}
results = []
for anagram in potential:
sets.append((set(anagram), anagram))
for x in sets:
if not ''.join(list(x[0])) in setCount:
setCount[''.join(list(x[0]))] = [x[1]]
elif len(setCount[''.join(list(x[0]))][0]) == len(x[1]):
setCount[''.join(list(x[0]))].append(x[1])
results += setCount[''.join(list(x[0]))]
print(list(set(results)))
答案 4 :(得分:0)
最简单的算法可能是通过质数。从每个字母到唯一质数的映射开始。前 26 个素数带你到 101。对于这两个词,取与字母对应的数字的乘积。由于合数的素数分解是唯一的,比较两个词的乘积可以验证它们是否是字谜。