【问题标题】:Why does my code return True when it should be False if the number of substrings do not equal each other?如果子字符串的数量不相等,为什么我的代码应该为 False 时返回 True?
【发布时间】:2020-06-03 19:36:38
【问题描述】:

目标是如果子串“cat”在str中出现的次数等于子串“dog”在str中出现的次数,则返回True。

我已经使用内置的str.count(sub) method 解决了这个问题,但现在我必须使用 1 个循环。这不是作业问题,只是为了我自己的练习。

不起作用的测试用例:

cat_dog('catxxdogxxxdog') --> True (should return False)
cat_dog('catxdogxdogxca') --> True (should return False)
cat_dog('dogdogcat') --> True (should return False)

谢谢!

def cat_dog(str):
  count1 = 0
  count2 = 0
  sub1 = 'cat'
  sub2 = 'dog'
  a = [sub1, sub2]
  if sub1 not in str and sub2 not in str:
    return True
  elif sub1 in str and sub2 not in str:
    return False
  elif str == '':
    return True
  for sub in a:
    if sub1 in str:
      count1 += 1
      if sub2 in str:
        count2 += 1
        if count1 == count2:
          return True
        else:
          return False
  else:
    return False

【问题讨论】:

  • if sub2 应与if sub1 处于同一级别,if count 应与for level 处于同一级别
  • 您是否使用过调试器查看为什么在这些情况下它返回True?
  • 不,我没有。即使调整缩进也不能解决问题。
  • 如果您不知道为什么会失败,您希望如何解决?

标签: python for-loop count substring


【解决方案1】:

首先,这是很多你想要做的代码。就像,str.count(substr) 会做你的工作。
但既然你想不使用它,我最后写了一些代码。

其次,代码为所有测试用例返回False(应该如此)。

这里,这是您想要的代码的更好版本(在 cmets 中有一些代码建议):

# Have an indentation of 4 SPACES for Python
#  
# `str` is a bad identifier name (as its a built-in class)
# So try using similar variables which are NOT reserved by Python
# 
# Also, write some documentation for what the function does right
# after the `:` function definition (in three quotes, for multi-line docstrings)
# (These can be read by using the built-in helper function `help(cat_dog)`
def cat_dog(text=''):
    """
    Returns True if *text* has equal no. of 'dog' and 'cat' substrings
else returns False
    """

    # Since words are surrounded by other words and empty characters
    # we subtract 1 from the total
    dog_count = len(text.split('dog')) - 1
    cat_count = len(text.split('cat')) - 1

    return dog_count == cat_count

这是另一个版本,与第一个类似,只是方式不同:

import re

def cat_dog(text=''):
    """
    same documentation
    """

    dog_count = len(re.findall('dog', text))
    cat_count = len(re.findall('cat', text))

    return dog_count == cat_count

【讨论】:

    【解决方案2】:

    您的问题与此代码段有关:

    for sub in a:
      if sub1 in str:
        count1 += 1
        if sub2 in str:
          count2 += 1
          if count1 == count2:
            return True
          else:
            return False
    

    在这里,如果sub 仅存在于str 中,则将count1 或count2 加一,这与sub 在字符串中出现的次数无关。例如,catxxdogxxxdog 会生成 count1 = 2 和 count2 = 2,因为对于 a 中的每个项目,计数都会增加一次。

    如果您不想使用str.count(sub),则需要自己遍历str,并计算每个字符串出现的次数。

    【讨论】:

      【解决方案3】:

      你的 for 循环不是为了做它打算做的事情而构建的。每次循环时,它都会发现每个子字符串实际上都在字符串中,因此它会增加每个计数,无论如何,您永远不会处理在循环的未来迭代中剥离该事件或移动到该子字符串的下一个事件。

      话虽如此,我还是建议您简单地使用内置的count 函数来节省大量时间。

      def cat_dog(str):
        return str.count("cat") == str.count("dog")
      

      或者,如果您仍然想手工操作而不需要太多复杂性,我可以推荐类似的方法:

      def cat_dog(str):
          count1 = 0
          count2 = 0
          sub1 = 'cat'
          sub2 = 'dog'
          index = 0
      
          while sub1 in str[index:]:
              count1 += 1
              index = str[index:].find(sub1) + 1 +index
      
          index = 0
      
          while sub2 in str[index:]:
              count2 += 1
              index = str[index:].find(sub2) + 1 +index
      
          return count1 == count2
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-01-30
        • 1970-01-01
        • 2021-11-18
        • 1970-01-01
        • 2018-11-09
        • 2010-11-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多