当我运行以下使用gcc
编译的代码(仅打开选项为-std=c99
)并运行可执行文件时,我会收到分段错误(msg core dumped)。
为什么?
#include <stdio.h>
int count_factors(int n, int i) {
int m = n;
if (m == i) {
return 1;
} else if (m % i == 0) {
while (m % i == 0) m = m / i;
return 1 + count_factors(m, i);
} else {
return count_factors(m, i+1);
}
}
int main() {
int streak_size = 4;
int streak = 0;
int solution = 0;
int n = 2;
while (solution == 0) {
n += 1;
int c = count_factors(n, 2);
if (c == streak_size) {
streak += 1;
} else {
streak = 0;
}
if (streak == streak_size) solution = n;
}
printf("%i", solution);
return 0;
}
答案 0 :(得分:2)
在您的递归中,您需要考虑一个基本案例。但是,有两个:
m == i
:当只有一个最大因素m == 1
:当存在多个最大因素您在m=4
和n=2
上进入无限循环,因为您错过了第二种情况。这里if (m % i == 0)
为真,因此while (m % i == 0) m = m / i;
运行。由于4是2的倍数,因此当m
为1时,此循环将结束。
再次递归时,您有m=1
和n=2
。这将触及else
子句,您可以使用count_factors
和m=1
再次致电n=3
。这种情况一直持续到堆栈爆炸为止。
添加第二个基本案例将修复无限递归:
int count_factors(int n, int i) {
int m = n;
if (m == i) {
return 1;
} else if (m == 1) {
return 0;
} else if (m % i == 0) {
while (m % i == 0) m = m / i;
return 1 + count_factors(m, i);
} else {
return count_factors(m, i+1);
}
}
实际上,你可以摆脱第一种情况,因为它只是if (m % i == 0)
的一个特例:
int count_factors(int n, int i) {
int m = n;
if (m == 1) {
return 0;
} else if (m % i == 0) {
while (m % i == 0) m = m / i;
return 1 + count_factors(m, i);
} else {
return count_factors(m, i+1);
}
}
程序然后运行完成,输出134046。
编辑:
它会在没有递归的情况下运行得更快:
int count_factors(int n, int i) {
int m = n;
int total = 0;
while (m != 1) {
if (m % i == 0) {
while (m % i == 0) m = m / i;
total++;
}
i++;
}
return total;
}
在我的机器上,递归版本大约需要9秒。迭代版本大约需要3秒钟。