【问题标题】:Segmentation fault in C recursive Combination (nCr)C 递归组合 (nCr) 中的分段错误
【发布时间】:2010-04-17 16:22:49
【问题描述】:

请帮帮我。该程序应该递归地找出两个数字的组合。 nCr = n!/ (r!(n-r)!)。我在 GCC 上编译它时收到此错误消息。

这是终端显示的内容:

输入两个数字: 8 4 分段错误


(程序退出,代码:139)

这里给出代码:

    #include<stdio.h>

float nCr(float, float, float);

int main()
{

 float a, b, c;
 printf("Enter two numbers: \n");
 scanf("%f%f", &a, &b);
 c = nCr(a, b, a-b);
 printf("\n%.3f", c);
 return 0;
}

float nCr(float n, float r, float p)
{

        if(n<1)
 return (1/(p*r))*(nCr(1, r-1, p-1));

 if(r<1)
 return (n/(p*1))*(nCr(n-1, 1, p-1));

 if(p<1)
 return (n/r)*(nCr(n-1, r-1, 1));

 return ( n/(p*r) )*nCr(n-1, r-1, p-1);
}

【问题讨论】:

  • 使用帕斯卡三角形要好得多,也更容易。
  • 你为什么要使用浮点数? int 已经足够好了:)
  • 我试图为 nCr 编写一个递归函数。在这种特殊情况下,int 对于除法精度来说不够好。

标签: c recursion segmentation-fault


【解决方案1】:

由于 nCr 没有任何非递归的 return 语句,它将无限递归。由于这会导致堆栈无限增长,因此您会遇到分段错误。

基本上,递归函数应该始终至少有一条可能的路径通过不递归的函数。否则你有无限递归。

【讨论】:

  • 并且看成 1! = 1,那将是您的非递归路径。我会将阶乘计算移至另一个函数,并使其成为具有递归的代码的唯一部分。
  • 感谢您的建议。 @sepp2k:所以我给出的基本情况是 if(n==1 && r==1 && p==1) return 1;但是我仍然遇到分段错误。错误代码 139。@peachykeen:是的,我在另一个程序中做到了。试图为 nCr 创建一个函数。
【解决方案2】:
  1. 为什么要使用浮点数?组合只处理整数...使用不涉及浮点运算的a formula。
  2. 无论发生什么,都会进行递归调用。这意味着您将拥有无限递归。这就是发生分段错误的原因。我建议你阅读我给你的链接,并使用那里给出的公式之一来实现你的程序。注意基本情况。

【讨论】:

  • 谢谢,维基百科清除了一些东西。使用“替代的,几乎等效的”计算,我重写了函数。得到数字不正确的结果,正在努力。
  • int comb(int n, int k) { if(k==1) return n;返回 (n/k)*comb(n-1, k-1); }
  • 您将n 除以k,您不应该这样做,因为您将进行整数除法或浮点运算,这两者都会导致不正确的结果。使用公式comb(n, k) = comb(n - 1, k - 1) + comb(n - 1, k) for 0 &lt; k &lt; n and 1 for k = 0 and k = n。
  • 做了浮点运算并且答案是正确的 - 使用维基百科中的值等等。一样的感谢。
  • 仅仅因为你得到了正确的结果并不意味着你的结果总是正确的。在处理组合时没有理由使用浮点数,我强烈建议你不要这样做,因为它会导致问题。
【解决方案3】:

你肯定会陷入无限递归来得到这个分段错误。正如 sepp2k 提到的那样,您基本上没有基本情况来停止递归。

【讨论】:

    【解决方案4】:

    您是否尝试过调试崩溃?您可以使用this page 作为参考。如果您可以发布有关崩溃的信息(堆栈跟踪等),这将有助于您自己和 SO 社区找出问题。

    【讨论】:

      猜你喜欢
      • 2022-01-20
      • 2017-06-05
      • 2018-03-30
      • 1970-01-01
      • 2017-12-25
      • 2019-05-26
      • 1970-01-01
      • 1970-01-01
      • 2021-08-01
      相关资源
      最近更新 更多