这是我在Collatz序列上的代码:
def collatz(a):
while (a != 1):
if a%2 == 0:
a = a//2
print (a, " -> ")
a = collatz(a)
elif a%2 != 0:
a = int(3*a + 1)
print (a, " -> ")
a = collatz(a)
x = int(input("Enter a number: "))
collatz(x)
我得到的输出对于输入的每个数字都是完美的,但是Jupyter Notebook也显示出某种错误。我在递归中犯了某种错误吗?我已经链接了显示的输出和错误。
答案 0 :(得分:1)
您执行a = collatz(a)
,但是由于您的函数没有return语句,因此会将a
设置为None。然后,在循环的下一个迭代中,您尝试对a进行算术运算。这将失败,因为您无法对None进行算术运算。
您实际上根本不需要递归。您已经有一个循环,因此您只需删除那些collatz调用即可。
def collatz(a):
while (a != 1):
if a%2 == 0:
a = a//2
print (a, " -> ")
elif a%2 != 0:
a = int(3*a + 1)
print (a, " -> ")
x = int(input("Enter a number: "))
collatz(x)
...但是,如果您对递归不满意,也可以这样做。删除while循环,然后在函数末尾调用collatz
。
def collatz(a):
if a == 1:
return
if a%2 == 0:
a = a//2
elif a%2 != 0:
a = int(3*a + 1)
print (a, " -> ")
collatz(a)
此方法的缺点是,如果函数重复执行999次以上,它将在“超过最大递归深度”的情况下崩溃。 Collatz序列很快收敛到1,因此对于特定算法而言,这可能不是一个实际问题,但是在编写任何递归函数时要牢记这一点。
这两种方法都具有在序列的最终编号之后打印“->”的潜在不良行为。在这种“边打印边打印”代码样式中,这是一个相当普遍的问题。一种可能的解决方案是从函数中删除打印调用,而不是返回序列值的列表。然后,您可以根据实际情况设置输出的样式,使用join
用箭头插入数字。
def collatz(a):
result = [a]
while (a != 1):
if a%2 == 0:
a = a//2
elif a%2 != 0:
a = int(3*a + 1)
result.append(a)
return result
x = int(input("Enter a number: "))
seq = collatz(x)
print(" -> ".join(str(num) for num in seq))