如何减少C中Collat​​z猜想程序中的数字

时间:2017-02-03 07:18:05

标签: c loops

目前我正在用C语言实现Collat​​z猜想问题。我能够打印特定数字的系列。例如,如果数字是25,则系列就像25 76 38 19 58 29 88 44 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1 = 2424是系列中元素的数量。现在我要打印系列的数量,直到1。例如25,24,...1

以下是我的尝试:

#include <stdio.h>

int main() {
    long x, a = 0;

    printf("Enter the value of X:");
    scanf("%lu", &x);
    printf("%ld ", x);

    for (i = x * x; i >= 1; i--) {
        if (x % 2 == 0) {
            x = x / 2;
            printf("%lu ", x);
            if (x == 1) {
                break;
            }
        } else {
            x = (3 * x) + 1;
            printf("%lu ", x);
            if (x == 1) {
                break;
            }
        }   
        a++;
    }
    printf(" = %lu\n", a + 2);
    return 0;
}

请帮我解决这个问题。

2 个答案:

答案 0 :(得分:1)

一个好主意是在函数中为1个元素设置Collat​​z函数。该函数将采用例如元素的参数。 25然后打印25年的collat​​z系列。

然后你可以围绕该函数运行一个循环,用参数24,23,22等调用它。这将为所有这些数字提供collat​​z系列。

我没有给出代码,因为你应该自己试试。

答案 1 :(得分:1)

您应该添加一个额外的循环,以便从x向下迭代到1

请注意,您的代码无法正确使用值1,并且不计算正确位置的输出数量,从而导致令人惊讶的+ 2最终调整。

将代码移动到单独的函数可以提高可读性。

你的保护循环没有意义:在x * x次迭代假定x * xunsigned long范围内时停止,这可能非常低(Windows上为x < 65536) 。较大的值可能会给出错误的结果。只是删除保护测试简化了代码,如果我们假设Collatz conjecture为真(已经测试了所有起始值高达2 60 ),任何产生无限循环的反例都会欢迎。

这是一个简化版和扩展版:

#include <stdio.h>

int main(void) {
    unsigned long xx, x, a;

    printf("Enter the value of X: ");
    if (scanf("%lu", &xx) != 1)
        return 1;

    for (; xx >= 1; xx--) {
        x = xx;
        a = 0;
        for (;;) {
            printf("%lu ", x);
            a++;
            if (x == 1)
                break;
            if (x % 2 == 0) {
                x = x / 2;
            } else {
                x = (3 * x) + 1;
            }
        }
        printf("= %lu\n", a);
    }
    return 0;
}