繁体   English   中英

在python中使用递归计算二进制间隙的程序会产生递归错误

[英]Program that calculates binary gap using recursion in python generates recursion error

我是编程新手(请注意 :)),我正在尝试编写一个函数,通过使用模函数收集整数的位,然后计算 0 之间的数量,使用递归计算数字的二进制间隙1 并显示两个 1 之间最长的链 0。

例如

Input = 10, Binary value = 1010, Binary Gap = 1
Input = 15, Binary value = 1111, Binary Gap = 0
Input = 41, Binary value = 101001, Binary Gap = 2

就目前而言,如果输入偶数,下面的代码将始终返回 0,如果使用奇数,则始终抛出递归错误。 这使我相信存在涉及除法的问题,并且它陷入了无限循环,但无法弄清楚原因。

def binary_gap(n, foundFirstOne= False, numofZeros= 0):
if n == 0:
    return 0
bit = n % 2
if bit == 1:
    ans = binary_gap((n / 2), True, 0)
else:
    if foundFirstOne == True:
        ans = binary_gap((n / 2), True, numofZeros+1)
    else:
        ans = binary_gap((n / 2), False, 0)
return ans and numofZeros
print(binary_gap(int(input("Please enter a number"))))

首先,编写一个递归函数将十进制转换为二进制(没有必要,因为已经有一个bin函数)。 然后,计算差距 - 在此使用递归是没有意义的,因为它太复杂了:

def convert_to_binary(n):
    if n > 1:
        return convert_to_binary(n // 2) + str(n % 2)
    return str(n % 2)

def binary_gap(n):
    b = convert_to_binary(n)
    x = b.split('1')[:-1]
    return max(len(d) for d in x)

print(binary_gap(10)) # 1
print(binary_gap(15)) # 0
print(binary_gap(41)) # 2

除了代码缩进问题之外,使用递归来解决这个问题太复杂了。 相反,您可以使用简单的strip()和这样的逻辑:

>>> def gap(n):
    ''' find the num's binary gap'''
    sn = bin(n)[2:].strip('0').split('1')
    print(sn)   # just to confirm. can comment out
    return max(len(s) for s in sn)

>>> gap(105); gap(120); gap(121); gap(15)
['', '', '0', '00', '']
2
['', '', '', '', '']
0
['', '', '', '', '00', '']
2
['', '', '', '', '']
0

在您的代码中,您在 2 种情况下从函数返回一个值:

  1. n == 0
  2. 该函数已到达最后一行( return ans and numOfZeroes

在第二种情况下,您在返回任何内容之前再次调用binary_gap 这意味着binary_gap将被重复调用,直到在其中一个函数调用中n == 0 ,这就是它将停止递归的时间。 但是,在任何情况下都不会使用n == 0调用您的函数,除非 0 是n的初始输入! 这就是你的函数无限递归的原因。

无需更改递归方法,可以使用更简单的技术在不递归的情况下解决此问题。 内置bin函数转换为二进制:

n = bin(n)
n = str(n)
n = n[2:]

我们转换为字符串,以便我们可以处理单个数字,并从第二个数字开始切片,因为所有 python 二进制数字在实际二进制数字之前以“0b”开头。

然后简单地计算最长的重复 0:

n = n.split("1")
print(max([len(zeroSet) for zeroSet in n]))

要回答所提出的实际问题,为什么会经历无限递归?

这是您的代码,还有一些额外的内容:

def binary_gap(n, foundFirstOne= False, numofZeros= 0, depth=0):
    print(f"recursion depth {depth}, n is {n}")
    if n < 0.001:
        print ("I think we've made our point. Use integer division.")
        return 0
    
    if n == 0:
        return 0
    bit = n % 2
    if bit == 1:
        ans = binary_gap((n / 2), True, 0)
    else:
        if foundFirstOne == True:
            ans = binary_gap((n / 2), True, numofZeros+1, depth+1)
        else:
            ans = binary_gap((n / 2), False, 0, depth+1)
    return ans and numofZeros

binary_gap(1)

递归深度 0,n 为 1
递归深度 0,n 为 0.5
递归深度 1,n 为 0.25
递归深度 2,n 为 0.125
递归深度 3,n 为 0.0625
递归深度 4,n 为 0.03125
递归深度 5,n 为 0.015625
递归深度 6,n 为 0.0078125
递归深度 7,n 为 0.00390625
递归深度 8,n 为 0.001953125
递归深度 9,n 为 0.0009765625
我想我们已经表达了我们的观点。 使用整数除法。

在解释器中比较这些:

1 / 2  
> 0.5  
1 // 2  
> 0  

如果需要,我很乐意评论更多关于如何在 python 中有效地做到这一点,使用模二算术。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM