【问题标题】:Anagram check in PythonPython中的字谜检查
【发布时间】:2014-08-25 21:10:22
【问题描述】:

我正在尝试编写一个程序来比较两个单词列表并检查单词以查看它们是否是字谜。

例如,

输入:['cinema','host','aab','train'], ['iceman', 'shot', 'bab', 'rain']

我正在使用以下代码:

#!/usr/bin/env python
anagram_dict = {}

def anagram_solver(first_words,second_words):
    for word in first_words:
         first_word = list(word)
         second_word = list(second_words[first_words.index(word)])
         first_copy = first_word
         second_copy = second-word
         if len(first_word) != len(second_word):
              anagram_dict[first_words.index(word)] = 0
         else:
              for char in first_word:
                  second_word = second_copy
                  if char in second_word:
                       first_copy.remove(char)
                       second_copy.remove(char)
                  else:
                      pass
              if len(first_copy) == len(second_copy):
                  print first_copy
                  print second_copy
                  anagram_dict[first_words.index(word)] = 1
              else:
                  anagram_dict[first_words.index(word)] = 0
    for k,v in anagram_dict.items():
    print "%d : %d" %(k,v)

if __name__ == "__main__":
     anagram_solver(['cinema','host','aab','train'],['iceman','shot','bab','rain'])

当我执行此脚本时,在 for 循环 for char in first_word: 中,循环被一个列表项跳过。例如,如果它正在处理列表['c','i','n','e','m','a'] 它只处理'c','n','m' 并忽略其他项目。如果我删除 list.remove(),那么它不会跳过项目。

人们可以执行这个脚本来更好地理解我在这里试图解释的内容。

只是想知道为什么会出现这种行为以及如何克服这个问题?

【问题讨论】:

  • 另外,请评论,处理此问题的有效方法(字谜检查)。
  • 为了高效的字谜检查,请注意sorted('host') == sorted('shot')
  • 为了有效地处理这个问题,你应该为每个单词建立一个规范的表示。然后使用== 简单地比较它们。最明显的规范表示,是按字母顺序对每个单词的字母进行排序(正如@jonrsharpe 54 秒前写的那样。aDmw it!)

标签: python python-2.x


【解决方案1】:

您可以简单地对单词进行排序并检查它们是否相等:

def anagram_solver(first_words, second_words):
    result = []
    for i in xrange(len(first_words)):
        a = list(first_words[i])
        b = list(second_words[i])
        a.sort()
        b.sort()
        
        result.append(a == b)
    return result

例子:

>>> a = ['cinema','host','aab','train']
>>> b = ['iceman', 'shot', 'bab', 'rain']
>>> anagram_solver(a, b)

[True, True, False, False]

【讨论】:

  • 与其在一个范围内循环,不如直接在带有for a, b, in zip(first_words, second_words)的单词上进行迭代。您也可以使用sorted,而不是列出一个列表,然后使用就地list.sort 方法。
【解决方案2】:

Python 通过引用处理列表,因此当您设置first_copy = first_word 时,实际上只是让first_copyfirst_word 指向同一个列表。您可以使用

来克服这种行为(实际上是复制列表)
first_copy = first_word[:]
second_copy = second_word[:]

【讨论】:

    【解决方案3】:

    根据标题回答您的问题:“Anagram check in Python”

    您可以在 one 三行中做到这一点:

    first_words = ['cinema','host','aab','train']
    second_words = ['iceman', 'shot', 'bab', 'rain']
    
    print [sorted(a) == sorted(b) for (a,b) in zip(first_words,second_words)]
    

    制作:

    [True, True, False, False]
    

    【讨论】:

      【解决方案4】:

      您可以将enumerate 与 sorted 一起使用:

      [sorted(a[ind]) == sorted(ele) for ind, ele in enumerate(b)]
      

      【讨论】:

        【解决方案5】:

        有两种方法可以做到这一点。一个很简单,另一个有点复杂,但是是最优的。 第一种方法

        def anagram1(s1,s2):
        # We need to get rid of the empty spaces and
        # lower case the string
        
        s1 = s1.replace(' ', '').lower()
        s2 = s2.replace(' ', '').lower()
        
        # Now we will return boolean for sorted match.
        return sorted(s1) == sorted(s2)
        

        下一个方法有点长:

        def anagram2(s1, s2):
        # We will remove spaces and will lower case the string
        s1 = s1.replace(' ', '').lower()
        s2 = s2.replace(' ', '').lower()
        
        # We will do the edge case to check if both strings have same number of letters
        if len(s1) != len(s2):
            return False
        
        # will creat an empty dictionary.
        count = {}
        
        for letter in s1:
            if letter in count:
                # We are assigning value 1 for every letter in s1
                count[letter] += 1
            # if it is the start of loop u just want to assign one into it.
            else:
                count[letter] = 1
        

        对于 s2,我们将做相反的事情。

        for letter in s2:
            if letter in count:
                # We are making every value of the letters from 1 to zero
                count[letter] -= 1
            else:
                count[letter] = 1
        
        for k in count:
            if count[k] != 0:
                return False
        
        # other wise just return true
        return True
        

        【讨论】:

          【解决方案6】:
          def anagram(string_one, string_two):
              string_one = string_one.replace(' ', '').lower()
              string_two = string_two.replace(' ', '').lower()
              string_list_one = []
              string_list_two = []
              for letters in string_one:
                  string_list_one.append(letters)
          
              for letters_t in string_two:
                  string_list_two.append(letters_t)
          
              string_list_one.sort()
              string_list_two.sort()
          
              if(string_list_one == string_list_two):
                  return True
              else:
                  return False
          

          【讨论】:

            猜你喜欢
            • 2017-05-19
            • 2021-12-12
            • 2013-12-07
            • 1970-01-01
            • 2016-03-18
            • 2014-04-13
            • 1970-01-01
            • 2021-10-10
            相关资源
            最近更新 更多