目前我正在用C语言实现Collatz猜想问题。我能够打印特定数字的系列。例如,如果数字是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 = 24
。 24
是系列中元素的数量。现在我要打印系列的数量,直到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;
}
请帮我解决这个问题。
答案 0 :(得分:1)
一个好主意是在函数中为1个元素设置Collatz函数。该函数将采用例如元素的参数。 25然后打印25年的collatz系列。
然后你可以围绕该函数运行一个循环,用参数24,23,22等调用它。这将为所有这些数字提供collatz系列。
我没有给出代码,因为你应该自己试试。
答案 1 :(得分:1)
您应该添加一个额外的循环,以便从x
向下迭代到1
。
请注意,您的代码无法正确使用值1
,并且不计算正确位置的输出数量,从而导致令人惊讶的+ 2
最终调整。
将代码移动到单独的函数可以提高可读性。
你的保护循环没有意义:在x * x
次迭代假定x * x
在unsigned 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;
}