在线性时间内检查anagram字符串

时间:2014-11-10 03:46:17

标签: python algorithm

因此,给定两个字符串的输入,我有以下线性时间解决方案来检查一个字符串是否是另一个的字谜。我想要一个更简洁和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"))

如何优化此功能?

5 个答案:

答案 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。对于这两个词,取与字母对应的数字的乘积。由于合数的素数分解是唯一的,比较两个词的乘积可以验证它们是否是字谜。