【问题标题】:How does this recursive function keep track of how many times it has been executed?这个递归函数如何跟踪它执行了多少次?
【发布时间】:2019-12-08 17:28:07
【问题描述】:

Project Euler 问题 14 给出以下问题:

为正整数集合定义以下迭代序列:

n → n/2(n 是偶数)
n → 3n + 1(n 为奇数)

使用上面的规则并从 13 开始,我们生成以下序列:

13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1

可以看出,这个序列(从 13 开始,到 1 结束)包含 10 个术语。虽然还没有被证明(Collat​​z Problem),但人们认为所有的起始数字都以 1 结束。

100 万以下的哪个起始数字产生最长的链?

我发现了这个递归函数,它计算给定数字的 Collat​​z 链的长度。数学逻辑非常简单易懂。但是,我不明白该函数如何跟踪链的长度。

代码如下:

def find_collatz_chain_length(x):
    if x == 1:
        print('here')
        return 1
    if x % 2 == 0:
        y = x // 2
        print(y)
    else:
        y = x * 3 + 1
        print(y)
    return find_collatz_chain_length(y) + 1

我添加了打印语句以在执行时遵循逻辑。例如:

print(find_collatz_chain_length(13))

然后我得到以下输出:

40 
20
10
5
16
8
4
2
1
here
10

这对我来说是有意义的,直到它返回链的长度 (10)。我知道这与最终 return 语句中的 +1 有关,因为更改它会导致错误的长度。如果有人可以向我解释该函数如何在没有列表或计数器的情况下跟踪长度,那就太好了。

【问题讨论】:

  • 想想return 声明。你要添加什么1 到?
  • 它要求函数返回 collat​​z 链的下一个值。我觉得答案正盯着我看,但我的大脑正在冻结。
  • that 函数调用会返回什么?

标签: python recursion


【解决方案1】:

让我们将函数调用替换为其返回值。我们从

find_collatz_chain_length(13)

这将返回

find_collatz_chain_length(40) + 1

查看函数调用,它会返回find_collatz_chain_length(20) + 1,但我们在第一次调用函数时已经有一个+ 1

(find_collatz_chain_length(20) + 1) + 1

那个函数调用返回find_collatz_chain_length(10) + 1

(((find_collatz_chain_length(10) + 1) + 1) + 1)

每次调用该函数时,它都会添加一个+ 1,直到函数的输入为1,此时它会停止调用自身并仅返回1。您最终会得到类似

(((((1) + 1) + 1) + 1) ... + 1)

每次调用函数时都有一个1。把它们加起来,你就得到了你的链条长度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    • 2020-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    相关资源
    最近更新 更多