C无限循环中的Collat​​z递归

时间:2016-05-06 09:07:31

标签: c recursion collatz

答案可能很明显,但对于我的生活,我看不到它。我试图找出用户提供的正整数收敛到1需要多少次迭代(即递归函数是f(x)= x / 2,如果x even,3x + 1,如果x odd)。如果做蛮力(即通过一系列if语句),答案是微不足道的。然而,我的目标是递归方法,并陷入无限循环:

#include <stdio.h>

int collatz(long number, int length)    
{

    while (number != 1)
    {
        length++;
        printf("%ld\n", number);
        if ((number % 2) == 0)
            collatz(number/2,length);
        else
            collatz(3*number+1,length);
    }

    return length;
}
int main()  
{
    long number;
    printf("Input a number\n");
    scanf("%ld", &number);
    int length=1;
    printf("length is %d", collatz(number,length));
    return 0;
}

number = 1时出现问题。它不是循环终止,而是继续,因此它会无限期地在1和2之间振荡。

3 个答案:

答案 0 :(得分:3)

语句while (number != 1)永远不会评估为false,因此只要您通过number != 1,就会陷入无限循环。

至于计算&#34;长度,&#34;您通过值传递,因此该函数不会计算到达1所需的Collat​​z迭代次数。相反,只需返回一个加上Collat​​z迭代次数以获得该数字的相应后继。例如,数字n所需的Collat​​z迭代次数为1加上n/23*n+1上合适的递归调用返回的数字,具体取决于{{1}分别是偶数或奇数。

这将有效:

n

答案 1 :(得分:0)

我同意@blazs。请注意,在while循环中你实际上没有修改变量号,所以当递归回滚到调用函数时,while循环将再次评估变量号的LOCAL副本(它没有改变),然后while循环将保持永远地去...... ..

答案 2 :(得分:0)

这也有效,解决了将变量副本传递给函数的范围问题:

    #include <stdio.h>

int collatz(long number, int length)    
{
    int temp=number;    
    int templength=length;  
    while (temp!= 1)
    {
        templength++;
        printf("%ld\n", number);
        if ((temp% 2) == 0)
            return collatz(temp/2,templength);
        else
            return collatz(3*temp+1,templength);
    }

    return templength;
}
int main()  
{
    long number;
    printf("Input a number\n");
    scanf("%ld", &number);
    int length=1;
    printf("length is %d", collatz(number,length));
    return 0;
}