最有效的方法-测试2个字串的字谜Python

时间:2019-10-15 14:05:28

标签: python python-3.x string iteration

testing if strings are anagrams有很多方法。但是,我想知道是否有一种方法可以仅对每个单词进行一次迭代吗?如果不是,那么用Python做到这一点的最有效方法是什么?

我们可以遍历第二个字符串,以检查第一个字符串中是否存在每个字符。但是,当使用内置 __contains__() 方法(称为__iter__()方法)时,在最坏的情况下(反转图),我们可以在第一个字符串上进行n-1次迭代。

def is_anagram(str_1, str_2):
  #chceck if same length
  if (len(str_1) != len(str_2)):
    return False
  else:
    #lowercase all characters  
    str1, str2 = list(str_1.lower()),list(str_2.lower())
    for letter in str1:
      if letter not in str2:
        return False
      str2.remove(letter)
    return True

还有其他方法吗?

4 个答案:

答案 0 :(得分:2)

如果您可以使用Collections.Counter,那么它将变得很简单,因为如果两个单词是字谜,它们将具有相同的键和相同的值。

from collections import Counter
def is_anagram(word1,word2):
    return Counter(word1)==Counter(word2)

word1 = 'ahbgrettf'
word2 = 'arethbfgt'

print(is_anagram(word1,word2)

如果使用defaultdict,可以添加到@Maxime的答案中,我们不必检查键是否存在,然后检查键是否匹配以及值是否匹配,以确定其字谜。

from collections import defaultdict

def is_anagram(word1,word2):
    table1, table2 = defaultdict(int), defaultdict(int)

    for c in word1:
        table1[c]+=1

    for c in word2:
        table2[c]+=1

    if set(table1.keys()) == set(table2.keys()):
        for k, v in table1.items():
            if table2[k]!=v:
                return False
    else:
        return False
    return True

print(is_anagram('ahbgrettf','arethbfgt'))

答案 1 :(得分:1)

也许有字典?

编辑:添加了丹的建议

word1 = 'ahbgrettf'
word2 = 'arethbfgt'


def is_anagram(word1, word2):

    if (len(word1) != len(word2)):
        return False

    word_dic = {}

    # n iterations
    for char in word1:
        if word_dic.get(char):
            word_dic[char] += 1
        else:
            word_dic[char] = 1

    # n iterations
    for char in word2:
        if word_dic.get(char):
            word_dic[char] -= 1
        else:
            return False

    # n iterations
    for v in word_dic.values():
        if v != 0:
            return False

    return True


print(is_anagram(word1, word2))

总计:3n吗?

答案 2 :(得分:0)

您可以使用defaultdict来使用默认值,并创建一个字母频率字典,并用O(3n)的另一个字符串从中减去

from collections import defaultdict

def is_anagram2(str_1, str_2):
    #check if same length
    if (len(str_1) != len(str_2)):
        return False
    #creates a dictionary with default value of 0 for all keys
    str_1_dict = defaultdict(int)

    #adds how many of each letter in the dictionary
    for i in str_1:
        str_1_dict[i] += 1
    #subracts how many of each letter in the dictionary
    for i in str_2:
        str_1_dict[i] -= 1
    #checks to make sure all values are 0 (same number of each letter in both strings)
    for i in str_1_dict:
        if not str_1_dict[i] == 0:
            return False
    return True
is_anagram2('aaaa','aaaa')

答案 3 :(得分:0)

我认为使用字典确实是最快的,因为排序至少需要 O(nlogn)。另一方面,创建字典应该有效地采用 O(n + n) 或 O(n)。 .get() 确保键是否已经存在,返回默认值 0,然后添加 1 以插入键并将字典中的值初始化为 1。最后,将两个字典等同可确保两个字典中存在相同的键:值对。或者,您可以检查两个字符串的长度,如果长度不匹配,则在开头返回 false。

def anagram_checker(str1, str2):
    str1 = str1.replace(" ", "").lower() #optional
    str2 = str2.replace(" ", "").lower() #optional

    str1_char_dict = {}
    str2_char_dict = {}

    for char in str1:
        str1_char_dict[char] = str1_char_dict.get(char, 0) + 1

    for char in str2:
        str2_char_dict[char] = str2_char_dict.get(char, 0) + 1

    return str1_char_dict == str2_char_dict