在'while循环'中实现印度算法。我做错了什么?

时间:2014-10-21 19:14:33

标签: c recursion

我被告知在while循环中实现函数而不是递归函数。到目前为止,我总是得到错误的答案。任何关于我犯错误的指标都将受到赞赏。 我正在尝试计算2 ^ 12,但到目前为止,每当我运行程序时它给了我4.原始问题然后我创建这个线程已经解决了。但我有一个与前一个问题有关的新问题,但需要采用不同的方法

#include <stdio.h>

double powerloop(double x, int y, double help)
{
   while(y!=0)
   {
     if((y%2)==0)
     {
        x=x*x;
        y=y/2;
     }

     if((y%2)==1)
     {
        help=help*x;
        x=x*x;
        y=(y-1)/2;
     }

     if(y==1)
     {
       x=x*help;
     }

     return x;
  }
}

int main(void){
     printf("Using powerloop to calculate 2^12: %f \n", powerloop(2, 12, 1));
     return 0;
}

5 个答案:

答案 0 :(得分:5)

两个问题:

1。以下测试错误:

if(y & 2 == 0)

你想要

if((y % 2) == 0)

模数%运算符与&#34;按位和&#34;不完全相同用2。

2. 初始线

 double num=power(x, y/2); 

导致堆栈溢出。在Visual C ++中,它也给了我一个明确的警告:&#34; C4717:&#39; power&#39;:递归所有控制路径&#34;

递归总是绝对需要一个停止的结束条件

你在power()中做的第一件事就是再次调用power(),再次,再次调用....再次:

double power(double x, int y) { 
    double num=power(x, y/2);    // <- call myself again forever
    // other code
 }

由于没有与该呼叫相关联的停止条件,您将永远调用power() - 或者直到总是有限的调用堆栈最终耗尽。

请记住,每次调用power()的返回地址至少都存储在堆栈中。将您的实现与正确的算法进行比较。你会发现第一个电话不在那里,而是更像是这样:

double power(double x, int y)
{

   if(x==0) {   
        return 0;  // stops recursion
   }

    if(y==0) {   
        return 1;    // stops recursion 
    }

    if( (y % 2) == 0) {
        num=num*num;
        y=y/2;
        return num;     // stops recursion
    }

    num=x*power(x, y-1);   // another recursive call
    y=y-1;
    return num;
 }

答案 1 :(得分:3)

你的无限递归

double power(double x, int y) { 
    double num=power(x, y/2); 
    /* .... */
 }

power()将无条件地自行调用。我没有检查算法本身,但你需要检查一下......

答案 2 :(得分:1)

毫无疑问,你正在遭遇堆栈溢出。

行:

double power(double x, int y)
{
   double num=power(x, y/2);

结果power呼叫power呼叫power呼叫power ......没有机会再回来。

每次调用函数时,返回地址都会被压入堆栈。你继续这样做,没有return来从堆栈中弹出地址,你最终会耗尽空间并获得段错误。

这个递归算法中的终止条件是缺少的,即执行 not 导致递归路径的代码路径。

答案 3 :(得分:1)

假设你称之为权力(3.0,10)。

你的功能首先要做的是调用电源(3.0,5)。

呼叫的第一件事是呼叫电源(3.0,2)。

呼叫的第一件事就是呼叫电源(3.0,1)。

调用的第一件事就是调用电源(3.0,0)。

调用的第一件事就是调用电源(3.0,0)。

调用的第一件事就是调用电源(3.0,0)。

调用的第一件事就是调用电源(3.0,0)。

调用的第一件事就是调用电源(3.0,0)。

调用的第一件事就是调用电源(3.0,0)。

...

几百万次呼叫后,您会收到“分段错误”。

答案 4 :(得分:1)

您的return x应该在最后if声明的范围内。