我在提交codechef小因子问题代码的解决方案时遇到SIGSEGV错误FCTRL2,尽管该代码在视频上运行良好编码语言C++4.3.2实例样本输入:4.1.2.5.3.样本输出:1.2.1206
#include <iostream>
using namespace std;
void fact(int n) {
int m = 1, a[200];
for (int j = 0; j < 200; j++) {
a[j] = 0;
}
a[0] = 1;
for (int i = 1; i <= n; i++) {
int temp = 0;
for (int j = 0; j < m; j++) {
a[j] = (a[j] * i) + temp;
temp = a[j] / 10;
a[j] %= 10;
if (temp > 0) {
m++;
}
}
}
if (a[m - 1] == 0) {
m -= 1;
}
for (int l = m - 1; l >= 0; l--) {
cout << a[l];
}
}
int main() {
int i;
cin >> i;
while (i--) {
int n;
cin >> n;
fact(n);
cout << endl;
}
return 0;
}
Caveat我不会直接为您修复代码,但我会强调哪里出了问题,以及为什么会出现seg错误。
您的问题在于如何实现逐位数乘法,特别是m
值的情况。通过每次递增时输出m
来测试它——你会发现它的递增频率比你想要的要高。你意识到你需要使用一种方法来达到158位数字,这是正确的,你的基本概念可以发挥作用。
第一条线索是,当你得到一个领先的0
时,用n = 6
进行测试,即使你试图用包含m-=1
的if
块来解决这个问题,你也不应该这样做
尝试使用n = 25
,您将看到的许多前导零。
任何大于此值的值都将失败,并出现分段错误。Seg错误是因为,使用此错误,您试图将数组a
的值设置为超出最大索引(因为m
大于200
)
N.B.您关于代码在Ideone.com上运行的断言在一定程度上是正确的——它将在n > 25
中失败。
(使用int计算阶乘的擦除代码)
代码中的问题是,每次temp
不为0时,对每个数字相乘都要增加m。当计算大阶乘时,由于m
变得太大,您可能会得到SIGSEGV。你看到它可能是因为0出现在你的结果前面。我想这就是你添加的原因
if (a[m - 1] == 0) {
m -= 1;
}
当内部循环完成并且术语不为空时,您应该只递增m
。一旦修复,你就可以去掉上面的代码。
void fact(int n) {
int m = 1, a[200];
for (int j = 0; j < 200; j++) {
a[j] = 0;
}
a[0] = 1;
for (int i = 1; i <= n; i++) {
int temp = 0;
for (int j = 0; j < m; j++) {
a[j] = (a[j] * i) + temp;
temp = a[j] / 10;
a[j] %= 10;
}
// if (temp > 0) {
// a[m++] = temp;
// }
while (temp > 0)
{
a[m++] = temp%10;
temp /= 10;
}
}
for (int l = m - 1; l >= 0; l--) {
cout << a[l];
}
}