【发布时间】:2017-03-06 16:00:18
【问题描述】:
编辑:当我将代码上传到自动测试平台时,程序不会在那里崩溃 - 它会返回正确的结果,但需要的时间太长(超过 5 秒)... wtf...强>
对于大学,我必须通过遵循 collatz 猜想来实现一个函数,该函数返回从输入达到 1 的步数。猜想很简单——给定任意整数:
1. 如果是偶数 - 除以二 (n/2)
2. 如果是奇数 - 乘以 3 并加一 (n*3+1)
猜想是所有数字最终都会达到1。我们不必证明或检查这一点,我们只需要返回对给定数字采取的步骤即可。
我们以前做过这个问题,但这次我们必须检查更大的数字(他们指定使用 long 而不是 int)AND 使用递归。他们给了我们框架代码,并要求我们只实现函数 - 所以我所有的代码都包含在里面
int lengthCollatz(long n) { //mycode }
main中的骨架代码收集两个输入值——a和b,其中a
我添加的函数似乎工作得很好,但是在较大的值(当输入 2 以百万计时)它似乎无缘无故崩溃并且没有给出错误。我已经尝试将所有内容更改为 unsigned longs 甚至 long longs 以查看是否有溢出 - 在这种情况下,程序就会卡住......我不明白出了什么问题,请帮我诊断错误。附言如何提高这些计算的速度?我们有 5 秒的限制。
我所有的代码都在 lengthCollatz 函数内(以及它上面的 length 全局变量)你能找出问题所在吗?
#include <stdio.h>
#define MAX64 9223372036854775807L /* 2ˆ63 -1 */
int length = 0;
int lengthCollatz(long n) {
length++;
//if not 1
if(n!=1){
//if odd
if(n&1) {
lengthCollatz(n=n*3+1);
}
//if even
else {
lengthCollatz(n/=2);
}
}
//if reached n = 1
else {
//return amount of steps taken
int returnLength = length;
length = 0;
return returnLength;
}
}
int main(int argc, char *argv[])
{
int n, a, b, len=-1;
scanf ("%d %d", &a, &b);
while (a <= b) {
int l = lengthCollatz(a);
if (l > len) {
n = a;
len = l;
}
a++;
}
printf("%d\n", n);
return 0;
}
更新功能:
int lengthCollatz(long n) {
if(n==1){
//return depthRecursion;
}
else {
if(n&1) {
n=n*3+1;
}
else {
n/=2;
}
return lengthCollatz(n);
}
}
【问题讨论】:
-
尝试通过调试器运行您的代码。它可能崩溃的唯一原因是由于递归太深导致的堆栈溢出。有时它会在没有消息的情况下退出,除非您使用调试器。
-
您的递归调用也不需要
n=n*3 + 1和n /= 2。只需使用n*3 + 1和n/2 -
你确定你应该使用递归吗?当您没有很好地处理所需的递归深度时,这只是在自找麻烦。
-
在任何情况下,使用文件范围变量来帮助您跟踪递归深度是不必要的,而且我有理由相信这不是您的讲师希望您做的事情。我认为这与您的问题无关,但我建议您考虑如何在不依赖任何文件范围变量的情况下执行计算。
-
您的递归调用忽略了函数的返回值。并不是所有的控制路径都返回一个值。您是否启用了编译器警告?