【问题标题】:Count consecutive digits in binary string计算二进制字符串中的连续数字
【发布时间】:2017-02-06 14:23:35
【问题描述】:

对于一个家庭作业问题,我们被要求定义一个函数来计算二进制字符串中连续数字的数量,并返回数字。

例如,对于二进制输入S = ‘1111000000001111000111111111111111’,函数应该返回n = [4,8,4,3,15]

到目前为止我有这个,但我知道它不正确,我不知道从这里去哪里。任何帮助将不胜感激!

def consecutive_length(s):
    if s == '':
        return 0
    if s[0] == 0:
        return 0
    return 1 + consecutive_length(s[1:])

注意: 我们不能使用任何循环。我们需要通过递归来做到这一点。

谢谢!

【问题讨论】:

  • 写一个简单的循环遍历字符串,跟踪最后找到的数字,每当下一个字符与被跟踪的字符相同时递增计数器。当字符发生变化时,将计数器添加到列表中并重新初始化计数器。
  • @innoSPG 这是我最初的想法,但我们不允许使用任何循环。

标签: python recursion binary compression


【解决方案1】:

这是一个有希望的pythonic方式(忽略递归解决这类问题不是pythonic的事实):

def consecutive_length(s):
    def sub(idx, lst, last_char, count):
        try:
            c = s[idx]     # c will be the 'next' char
        except IndexError: # no more chars left to process
            if count:
                lst.append(count)
            return lst
        if c != last_char:
            lst.append(count)
            count = 0
        return sub(idx+1, lst, c, count+1)                            
    return sub(0, [], s[0] if s else None, 0)

在哪里

  • 外部函数只是将字符串作为参数,并隐藏内部函数的附加参数
  • idx 是字符串的索引,我们不会在每次递归调用时分配一个新字符串(并且 s[idx] 是 O(1) iirc)
  • 我们不计算字符串的长度,而是等待异常发生(EAFP - 请求宽恕比请求许可更容易)

测试:

>>> print consecutive_length('1111000000001111000111111111111111')
[4, 8, 4, 3, 15]    
>>> print consecutive_length('1111000000001111000111111111111110')
[4, 8, 4, 3, 14, 1]
>>> print consecutive_length('1')
[1]
>>> print consecutive_length('0')
[1]
>>> print consecutive_length('')
[]

【讨论】:

    【解决方案2】:

    我在这里假设“11”是一个连续的 1 序列。所以“111”有 2 个连续的。这个解决方案是,如果循环不是问题。使用索引找到“11”并继续这样做,直到找不到更多。下面的程序显示了连续 1 的数量。

    cnt = 0
    pos = -1
    while True:
        try:
            pos = '111001100101111'.index('11', pos+1)
            cnt += 1
        except ValueError:
            print cnt
            break
    

    结果:

    6
    

    【讨论】:

      【解决方案3】:

      编辑:uselpa 有更好的方法。

      因为不允许循环:

      def consecutive_length(s, output, prev_char, count):
          # if end of string, append last count and return output
          if s == '':
              output.append(count)
              return output
          # if curr_char is same as prev_char, add 1 to count and parse next char
          if s[0] == prev_char:
              return consecutive_length(s[1:], output, s[0], count + 1)
          # if curr_char is diff from prev_char, append count and reset count to 1
          else:
              prev_char = s[0]
              output.append(count)
              return consecutive_length(s[1:], output, s[0], 1)
      

      使用consecutive_length(s, [], s[0], 0) 调用它。

      【讨论】:

      • 有没有办法做到这一点而无需任何额外的输入,只使用字符串作为输入?
      • 发布家庭作业解决方案对学生没有帮助。最好的方法是指导 OP 解决问题,同时了解他在做什么。否则,我们最终会遇到无法独立推理的毕业生。
      • 哦。抱歉,innoSPG。我认为添加 cmets 将有助于解释其背后的逻辑。虽然最后还是把作业的推理这一步去掉了。
      • @uselpa,抱歉,忘记添加了。让我编辑答案以提供默认值。
      • 只是else: 行,而不是之后的代码,因为在那之前有一个return。与您在函数开始时所做的相同。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多