C 序列的递归函数,用于处理sqrt(2)的连续分数表示的分子

C 序列的递归函数,用于处理sqrt(2)的连续分数表示的分子,c,function,recursion,C,Function,Recursion,我尝试开发一个递归函数,用于查找序列的第n项(1,1,3,7,17,41,992395771393…),但没有成功: int progRec(int n){ return 2*progRec(n-1) + progRec(n-2);} 有什么想法吗?添加停止条件。我假设它是1,如果n你知道这个序列是如何工作的吗?如果你这样做了,你应该解释一下。你的函数在什么时候停止递归?在堆栈溢出@Jacobi很好,你理解了它,但是你把它作为一个“猜测序列”的谜题呈现给读者。你的递归缺少一个停

我尝试开发一个递归函数,用于查找序列的第n项(1,1,3,7,17,41,992395771393…),但没有成功:

int progRec(int n){
        return 2*progRec(n-1) + progRec(n-2);}

有什么想法吗?

添加停止条件。我假设它是
1,如果n你知道这个序列是如何工作的吗?如果你这样做了,你应该解释一下。你的函数在什么时候停止递归?在堆栈溢出@Jacobi很好,你理解了它,但是你把它作为一个“猜测序列”的谜题呈现给读者。你的递归缺少一个停止条件。当然,这个递归非常次优,因为它多次计算相同的元素。C语言没有默认的argumentsTrue,只需使用一个包装函数。您的第二个递归函数是一个巨大的速度改进。我做了基准测试。对于
n=2
orig=87ns
fast=55ns
。对于
n=40
orig=398ms
fast=170ns
。对于
n=99
fast=270ns
[而orig是“表外”]。顺便说一句,我也做了循环版本,速度稍微快了一点,在
n=99时从最初的6ns下降到1ns。因此,orig的时间每增加
n
就增长50%,并且fast相对保持
O(n)
@CraigEstey第二个版本是尾部递归,所以它的执行方式与循环类似也就不足为奇了。@EugeneSh。我也这么认为,因为Toribio提到了这一点,但为了简单起见,我想编写循环版本。分解后的
-O3
版本似乎会逐字节生成相同的指令,因此任何速度差异都是舍入误差。
int progRec(int n) {
    if (n <= 2) {
        return 1;
    }
    return 2 * progRec(n - 1) + progRec(n - 2);
}
int progRec(int n, int val = 1, int prev = 1) {
    return n <= 2 ? val : progRec(n - 1, 2 * val + prev, val);
}