【问题标题】:Segmentation fault for recursive function in CC中递归函数的分段错误
【发布时间】:2017-12-25 13:43:38
【问题描述】:

递归函数FastExp使用算法计算(a^n)(mod m):

  • a^n = 1,如果 n=0;
  • a^n = [a^(n/2)]^2,如果 n 是偶数;和
  • a^n = a(a^[(n-1)/2])^2 如果 n 是奇数。

现在我确定算法是正确的,并且我完全遵循了它,但是当我尝试运行我的代码时出现了分段错误。这是我的代码 -

`#include <stdio.h>

/* function prototype */
int FastExp(int a, int n, int m);

/* There is no error in the main function */  
int main()
{
    int a, n, m;

    printf("Enter three positive numbers a n m: ");
    scanf("%d %d %d", &a, &n, &m);
    printf("%d^%d(mod %d) is %d\n", a, n, m, FastExp (a, n, m));

    return 0;
}


/*
 * FastExp(a, 0, m) is 1.
 * FastExp(a, 1, m) is a.
 * x = FastExp(a, n/2, m)
 * FastExp(a, n, m) is x2(mod m) if n is even
 * FastExp(a, n, m) is x2a(mod m) if n is odd
 */

/* There is some error in this function */
int FastExp(int a, int n, int m) 
{ 

    int an;

    if (n == 0)
    {
        an = 1;
        return an;
    }
    //even  
    if (n % 2 == 0)
    {
        an = FastExp (a, n/2, m);       // an = a^(n/2)
        an = FastExp (an, 2, m);        // an = [a^(n/2)]^2
        return an;
    }   
    // odd
    if (n % 2 == 1)
    {
        an = FastExp (a, (n-1)/2, m);   // an = a^[(n-1)/2]
        an = FastExp (an, 2, m);        // an = {a^[(n-1)/2]}^2
        an = an*a;
        return an;
    } 

    return (an % m);

}

我猜它会陷入无限循环,但我不确定如何纠正这个问题。我犯了一些基本错误吗?谁能解释一下如何用最少的指令更改来纠正它?

【问题讨论】:

    标签: c recursion infinite-loop


    【解决方案1】:

    n == 1n == 2 的情况下你没有停止递归。

    我不太了解您的代码...通过阅读 FastExpr 的 cmets,我得出了这个完全不同的结果。我在这里遗漏了什么吗?

    /*
     * FastExp(a, 0, m) is 1.
     * FastExp(a, 1, m) is a.
     * x = FastExp(a, n/2, m)
     * FastExp(a, n, m) is x2(mod m) if n is even
     * FastExp(a, n, m) is x2a(mod m) if n is odd
     */
    int FastExp(int a, int n, int m)
    {
      int x;
      if (n == 0) return 1;
      if (n == 1) return a;
      x = FastExpr(a, n / 2, m);        // <-- Good. Converges to zero.
      x *= x;
      return (n & 1) ? ((x * a) % m) : (x % m);
    }
    

    【讨论】:

    • 老实说,您的代码看起来像是一个更简单的应用程序实现,但由于某种原因,它没有给出正确的输出。例如,(3^2)(mod 4) 给出 3 而不是 1,(3^10)(mod 5) 给出 4 而不是 2。我不知道为什么。但是,您建议在我的代码中包含 n==1 和 n==2 的情况!
    • 我有偶数和奇数混合。现在修好了。但我真的不知道应用程序是什么。我刚刚路过你的cmets。
    • 应用程序只是使用快速指数算法计算所需的表达式。
    【解决方案2】:

    你有递归调用FastExp (an, 2, m)。这导致无限递归

    它是无限的,因为在递归调用中n 是偶数所以你调用FastExp (an, 2, m)。在那个电话n 中,你甚至可以打电话给FastExp (an, 2, m)。以此类推。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-14
      • 2019-08-13
      • 2013-03-05
      • 2014-11-05
      • 2019-11-16
      相关资源
      最近更新 更多