【问题标题】:How to check whether two words are anagrams python如何检查两个单词是否是字谜python
【发布时间】:2019-09-20 15:43:46
【问题描述】:

我正在处理一个简单的问题:

  • 检查两个字符串是否是字谜。

我写了一个简单的代码,可以检查两个字符串,比如 'abcd' 和 'dcba' 是字谜,但我不知道如何处理更复杂的字谜,例如“Astronomer”和“Moon starter”。

line1 = input('Enter the first word: ')
line2 = input('Enter the second word: ')

def deleteSpaces(s):
    s_new = s.replace(" ","")
    return s_new


def anagramSolution2(s1,s2):
    alist1 = list(deleteSpaces(s1))
    alist2 = list(deleteSpaces(s2))

    print(alist1)
    print(alist2)

    alist1.sort()
    alist2.sort()

    pos = 0
    matches = True

    while pos < len(deleteSpaces(s1)) and matches:
        if alist1[pos]==alist2[pos]:
            pos = pos + 1
        else:
            matches = False

    return matches

首先我认为问题在于使用空格,但后来我明白如果字符串大小不同,我的算法就不起作用。

我不知道在这种情况下该怎么办。

在这里我找到了一个漂亮的解决方案,但它也不起作用:

def anagrams(s1,s2):
    return [False, True][sum([ord(x) for x in s1]) == sum([ord(x) for x in s2])]

如果我运行这个函数并在两个字符串上测试它,我会得到这样的输出:

Examples:

First Word: apple
Second Word: pleap

output: True

First Word: Moon starter
Second Word: Astronomer

output: False //however it should should be True because this words are anagrams 

【问题讨论】:

  • 不起作用是什么意思?
  • 我的意思是它返回False,而它应该是True
  • 请举例说明清楚。
  • 另外,我猜你的程序的问题在于案例。但我不太确定,因为没有足够的例子。
  • @MagnusBuvarp No. 例如"aabc""abcc" 在这种情况下是正确的,这是错误的。

标签: python string sorting


【解决方案1】:

你的算法没问题。您的问题是您不考虑大小写字母。改变两行

alist1 = list(deleteSpaces(s1))
alist2 = list(deleteSpaces(s2))

alist1 = list(deleteSpaces(s1).lower())
alist2 = list(deleteSpaces(s2).lower())

将解决您的问题。 作为替代方案,您可以简单地使用以下函数:

def anagrams(s1, s2):
    def sort(s):
        return sorted(s.replace(" ", "").lower())
    return sort(s1) == sort(s2)

如果你想有一个复杂度为 O(n) 的更快的解决方案,你应该使用 Counter 而不是对这两个词进行排序:

from collections import Counter

def anagrams(s1, s2):
    def get_counter(s):
        return Counter(s.replace(" ", "").lower())

    return get_counter(s1) == get_counter(s2)

【讨论】:

    【解决方案2】:

    正如其他人指出的那样,您的算法给出了“错误”结果,因为 Moon starterAstronomer 实际上不是字谜。

    您可以通过简单地使用可用的对象方法来大幅改进您的算法。它们已经提供了所有功能。

    def normalize_str(s):
      return s.replace(" ","").lower()
    
    def anagramSolution2(s1,s2):
      return sorted(normalize_str(s1)) == sorted(normalize_str(s2))
    

    normalize_str 就像您的deleteSpaces,但它也将所有内容都转换为小写。这样,Moonmoon 将比较相等。最后你可能想要做更严格或更宽松的规范化,这只是一个例子。

    sorted 的调用已经为您提供了list,您不必进行显式转换。此外,通过== 进行的list 比较将明智地比较lists 元素(您对for 循环所做的事情),但效率更高。

    【讨论】:

      【解决方案3】:

      这样的?

      $ cat /tmp/tmp1.py
      #!/usr/bin/env python
      
      def anagram (first, second):
          return sorted(first.lower()) == sorted(second.lower())
      
      if __name__ == "__main__":
          for first, second in [("abcd  rsh", "abcd x rsh"), ("123 456 789", "918273645  ")]:
              print("is anagram('{0}', '{1}')? {2}".format(first, second, anagram(first, second)))
      

      给出:

      $ python3 /tmp/tmp1.py
      is anagram('abcd  rsh', 'abcd x rsh')? False
      is anagram('123 456 789', '918273645  ')? True
      

      【讨论】:

        【解决方案4】:
        a=input("string1:");
        b=input("string2:");
        
        def anagram(a,b):
        
            arra=split(a)
            arrb=split(b)
            arra.sort()
            arrb.sort()
        
            if (len(arra)==len(arrb)):
        
                    if(arra==arrb):
                        print ("True")
                    else:
                        ana=0;
                        print ("False");
        
            else:
                print ("False");
        
        
        
        def split(x):
            x=x.replace(' ','').lower()
            temp=[]
            for i in x:
                temp.append(i)
            return temp;
        
        
        anagram(a,b)
        

        【讨论】:

          【解决方案5】:

          懒惰的做法,但超级干净:

          def anagram(a,b):
               return cleanString(a) == cleanString(b)
          
          def cleanString(string):
              return ''.join(sorted(string)).lower().split()
          

          【讨论】:

            【解决方案6】:
            def anagram(str1,str2):
                l1=list(str1)
                l2=list(str2)
                if sorted(l1) == sorted(l2):
                    print("yess")
                else:
                    print("noo")
            str1='listen'
            str2='silent'
            anagram(str1,str2)
            

            虽然不是最优化的解决方案,但效果很好。

            【讨论】:

              【解决方案7】:

              我发现这是最好的方法:

              from collections import Counter
              
              def is_anagram(string1, string2):
                  return Counter(string1) == Counter(string2)
              

              【讨论】:

                【解决方案8】:

                我试过了,效果很好

                def is_anagram(word1,word2):
                        a = len(word1)
                        b = len(word2)
                        if a == b:
                            for l in word1:
                                if l in word2:
                                    return True
                        return False
                

                【讨论】:

                  猜你喜欢
                  • 2013-02-09
                  • 2015-05-04
                  • 2014-09-03
                  • 2011-05-13
                  • 2017-08-12
                  • 2021-01-11
                  • 2016-04-07
                  • 2017-12-02
                  相关资源
                  最近更新 更多