【发布时间】:2020-01-29 07:24:29
【问题描述】:
问题是找到最长的collatz系列存在的数字i
事实上,collatz 系列对于所有数字总是以 1 结束。
因此,任何数字都不会在其 collatz 系列中重复。使用这个事实,我编写了以下代码 逻辑: 我开始一个while循环,一直到n,并且对于每次迭代,我都为那个i存储系列的长度。 如果 i 出现在一些 n >= r > i 的序列中,则 i 终止循环并将 i 的长度添加到 r。 例如,假设 3 的序列是 3、10、5、16、8、4、2、1。现在对应于 2 的长度已经存储在 series_length 数组中,所以我使用该值。
然后是旁边的 for 循环,找到最长的系列并显示答案。
准确地说,n
代码:
#include <stdio.h>
int length = 0, series_length[500000], maxlength = 0;
void store_length(int n) {
while(n > 1 && series_length[n] == 0) {
length++;
if(n%2 == 0) {
n = n/2;
}
else {
n = 3*n + 1;
}
}
length += series_length[n];
}
int main() {
int n, i = 1, result;
scanf("%d", &n);
series_length[1] = 1;//redundant statement
while(i <= n) {
store_length(i);
series_length[i] = length;
length = 0;
i++;
}
for(int i = 1;i <= n; i++) {
if(maxlength <= series_length[i]) {
maxlength = series_length[i];
result = i;
}
}
printf("%d %d\n", result, maxlength);
return 0;
}
输入- 10 输出- 9 20(如预期)
输入- 100000 输出- 分段故障 预期的- 77031 351
【问题讨论】:
-
很可能是数组访问越界;在所有数组索引周围使用
if语句进行简单检查。 -
您似乎相信
series_length[500000]创建了一个索引从 1 到 500000,而索引从 0 到 499999 的数组。 -
您的
store_length函数没有检查n是否已超过50000(实际上您的代码最多只能处理49999,这是您的数组支持的最大索引)。输入 1819,n 最终变为 52487,此时您的索引超出了数组的末尾。当您的索引 >= 50000(或 > 50000,如果您将数组大小增加一)时,您需要添加一个检查以停止访问数组。 -
使用值 100000 运行代码会溢出数组
series_length。 n 达到值 504466。您必须增加series_length数组的大小或更改算法。 -
再测试一下,我发现对于 n = 500000,该值可以大于 1,047,216,490 !我没有进一步探索。你肯定超过了 32 位整数的大小。您需要使用
long long int作为n的类型。这种大小的数组变得巨大。当n为 500000 时,您应该探查您获得的最大值。
标签: c arrays segmentation-fault collatz