【问题标题】:How to check for partial anagram in Python 3如何在 Python 3 中检查部分字谜
【发布时间】:2013-12-07 19:53:39
【问题描述】:

非常感谢您关注这个问题。

我真的被一个特定的问题困住了,我将在下面发布问题:

定义一个函数partial anagram (str1, str2),如果每个字母都返回True str1 中出现的次数至少与str2 中出现的次数相同,否则返回 False。

(注意:str2 中可能有其他字母不会出现在 str1 中,这就是为什么 str1 只是str2 的部分变位词。)[4 分]

提示:如果将str2 转换为列表,则可以循环遍历str1 中的字符,检查每个字符是否存在于str2 中。如果它不存在,则 str1 不能是 str2 的部分变位词(因此返回 False)。如果存在,则需要从列表中删除该字符(因为它已用完),然后继续循环。如果你循环遍历 str1 中的所有字符并且总是和 str2 中的匹配,那么你可以返回 True。

这是我的代码:

def partial_anagram(str1,str2):
    str2_list = list(str2)
    for char in str1:
        if char in str2_list:
            str2_list.remove(char)
            return True
        else:
            return False

【问题讨论】:

  • 为什么在 for 循环中有return str2_list?您的要求说您应该只返回TrueFalse
  • 这看起来是一个有趣的问题,但是这个函数的预期用途是什么?

标签: python python-3.x


【解决方案1】:

您唯一的错误似乎是您的函数提前返回。当你的hint提议then carry on looping时,通过发出return声明你结束你的函数并返回True。您的代码稍作修改,对我来说似乎是正确的:

def partial_anagram(str1, str2):
    str2_list = list(str2)
    for char in str1:
        if char in str2_list:
            str2_list.remove(char)
        else:
            return False
    return True

但我不太喜欢你的作业中的提示和建议的解决方法。至于我,我会以其他方式解决这个任务:

from collections import Counter

def partial_anagram_counter(a, b):
    if Counter(a) - Counter(b):
         return False
    return True

>>> partial_anagram_counter('abacaba','aabbaaccaabbaa')
True
>>> partial_anagram('abacaba','aabbaaccaabbaa')
True

【讨论】:

    【解决方案2】:

    我认为这样的事情就足够了:

    def partial_anagram(str1, str2):
        return not False in [str1.count(x) <= str2.count(x) for x in str1]
    

    这会生成一个列表,对于str1 中的每个字符,该列表是一个布尔值,指示str2 是否包含至少与str1 一样多的该字符。如果False 出现在该列表中,则str1 中至少有一个字符出现的次数比str2 中的次数多。

    不检查每个重复字符可能会更有效,但只要你的字符串相对较小,效率上的提升可能不值得额外的代码。 @iCodez 的答案通过 Counter 类采用了该优化,并且对于较大的字符串可能更有效。

    【讨论】:

    • 执行for x in set(str1) 将停止重复检查。
    【解决方案3】:

    如果我理解正确,那么这应该是你想要的:

    >>> from collections import Counter
    >>> def partial_anagram(str1, str2):
    ...     return not bool(Counter(str1)-Counter(str2))
    ...
    >>> partial_anagram('abc', 'abc')
    True
    >>> partial_anagram('abc', 'cba')
    True
    >>> partial_anagram('abc', 'cb')
    False
    >>> partial_anagram('abac', 'cba')
    False
    >>> partial_anagram('abac', 'acbad')
    True
    >>>
    

    请注意,上述解决方案使用了一种称为collections.Counter 的特殊工具。但是,如果不允许您使用此类,则可以这样做:

    >>> def partial_anagram(str1, str2):
    ...     return all(str2.count(x) >= str1.count(x) for x in set(str1))
    

    【讨论】:

      【解决方案4】:

      如果你有一个初始值为 0 的变量怎么办。然后在那个 for 循环中,当 str2 有一个字符在 str1 中时,你可以增加这个变量。

      最后,如果变量的值等于str1的长度,那么你知道str2包含str1中的所有字符。

      def partial_anagram(str1,str2):
          b=0
          str2_list = list(str2)
          for char in str1:
              if char in str2_list:
                  str2_list.remove(char)
                  b+=1
          if b==len(str1):
              return True
          else:
              return False
      

      您也可以使用它来检查完整的字谜。如果b等于str2str1的长度,那么str1str2将有完全相同的字符,你应该可以自己写(只需添加@987654332 @ 在最后的 if 语句中)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-12-23
        • 2017-05-19
        • 1970-01-01
        • 2021-12-12
        • 2013-11-25
        • 1970-01-01
        • 2012-11-07
        • 2012-01-01
        相关资源
        最近更新 更多