Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 递归求幂_C_Algorithm_Recursion - Fatal编程技术网

C 递归求幂

C 递归求幂,c,algorithm,recursion,C,Algorithm,Recursion,因此,我必须编写一个用于求幂的递归算法,我必须使用它来加快算法:然后我必须计算出发生了多少次乘法。我写的,但我不确定我是否正确-我还需要一些帮助来计算乘法部分 #include <stdio.h> #include <math.h> double intpower(double x, int n) { double result; if(n>1&&n%2!=0) {result=x*intpower(x,(n-1)/2)*intpo

因此,我必须编写一个用于求幂的递归算法,我必须使用它来加快算法:然后我必须计算出发生了多少次乘法。我写的,但我不确定我是否正确-我还需要一些帮助来计算乘法部分

#include <stdio.h>
#include <math.h>

double intpower(double x, int n)
{
    double result;
    if(n>1&&n%2!=0) {result=x*intpower(x,(n-1)/2)*intpower(x,(n-1)/2);}
    if(n>1&&n%2==0) {result=intpower(x,n/2)*intpower(x,n/2);}
    if(n==1) return x;
    else return result;
}


int main()
{
    int n;
    double x,result;
    printf("x\n");
    scanf("%lf", &x);
    printf("n\n");
    scanf("%d", &n);
    printf("result = %.2f\n", intpower(x,n));


    return 0;
}
#包括
#包括
双整数幂(双x,整数n)
{
双重结果;
如果(n>1&&n%2!=0){result=x*intpower(x,(n-1)/2)*intpower(x,(n-1)/2);}
如果(n>1&&n%2==0){result=intpower(x,n/2)*intpower(x,n/2);}
如果(n==1)返回x;
否则返回结果;
}
int main()
{
int n;
双x,结果;
printf(“x\n”);
扫描频率(“%lf”、&x);
printf(“n\n”);
scanf(“%d”和“&n”);
printf(“结果=%.2f\n”,intpower(x,n));
返回0;
}

归纳定义是

  • 如果k是偶数,那么x^k=[x^(k/2)]^2
  • 如果k是奇数,那么x^k=x*[x^(楼层(k)/2)]^2
  • 通过这些,可以更容易地了解如何安排递归:

    #include <stdio.h>
    
    double int_pwr(double x, unsigned k)
    {
      if (k == 0) return 1;
      if (k == 1) return x;  // This line can be omitted.
      double y = int_pwr(x, k/2);
      return (k & 1) ? x * y * y : y * y;
    }
    
    int main(void)
    {
      double x;
      unsigned k;
      scanf("%lf%u", &x, &k);
      printf("x^k=%lg\n", int_pwr(x, k));
      return 0;
    }
    
    #包括
    双积分压水堆(双x,无符号k)
    {
    如果(k==0)返回1;
    如果(k==1)返回x;//这一行可以省略。
    双y=int_压水堆(x,k/2);
    返回(k&1)?x*y*y:y*y;
    }
    内部主(空)
    {
    双x;
    无符号k;
    scanf(“%lf%u”、&x和&k);
    printf(“x^k=%lg\n”,int_pwr(x,k));
    返回0;
    }
    
    我已将类型更改为更具逻辑性的类型,并通过在每个级别上进行两次递归调用,节省了OP解决方案所做的指数级(以k为单位)工作量


    至于乘法的数量,很容易看出,如果
    k
    的最高阶位是2^p(即在位置p),那么重复平方需要p次乘法。另一种说法是p=floor(log_2(k))。例如,如果k=4=2^2,将平方得到答案:2次乘法。此外,您还需要q-1,其中q是
    k
    的二进制表示中的1数。这是检查“奇数”为真的次数。也就是说,如果k=5(其中2位为1),则将平方与结果相乘一次。总而言之,乘法的数目是p+q-1,其中p和q的定义如上所述。

    归纳定义如下

  • 如果k是偶数,那么x^k=[x^(k/2)]^2
  • 如果k是奇数,那么x^k=x*[x^(楼层(k)/2)]^2
  • 通过这些,可以更容易地了解如何安排递归:

    #include <stdio.h>
    
    double int_pwr(double x, unsigned k)
    {
      if (k == 0) return 1;
      if (k == 1) return x;  // This line can be omitted.
      double y = int_pwr(x, k/2);
      return (k & 1) ? x * y * y : y * y;
    }
    
    int main(void)
    {
      double x;
      unsigned k;
      scanf("%lf%u", &x, &k);
      printf("x^k=%lg\n", int_pwr(x, k));
      return 0;
    }
    
    #包括
    双积分压水堆(双x,无符号k)
    {
    如果(k==0)返回1;
    如果(k==1)返回x;//这一行可以省略。
    双y=int_压水堆(x,k/2);
    返回(k&1)?x*y*y:y*y;
    }
    内部主(空)
    {
    双x;
    无符号k;
    scanf(“%lf%u”、&x和&k);
    printf(“x^k=%lg\n”,int_pwr(x,k));
    返回0;
    }
    
    我已将类型更改为更具逻辑性的类型,并通过在每个级别上进行两次递归调用,节省了OP解决方案所做的指数级(以k为单位)工作量


    至于乘法的数量,很容易看出,如果
    k
    的最高阶位是2^p(即在位置p),那么重复平方需要p次乘法。另一种说法是p=floor(log_2(k))。例如,如果k=4=2^2,将平方得到答案:2次乘法。此外,您还需要q-1,其中q是
    k
    的二进制表示中的1数。这是检查“奇数”为真的次数。也就是说,如果k=5(其中2位为1),则将平方与结果相乘一次。总而言之,乘法的次数是p+q-1,其中p和q的定义如上所述。

    要计算乘法发生的次数,可以在
    intpower()中对它们进行计数。


    要计算乘法运算的次数,可以在
    intpower()
    中对它们进行计数

    试试这个

    double intpower(double x, int n)
    {
        if(n == 0) return 1;
        if(n == 1) return x;
        if(n%2!=0)
        {
            return x*intpower(x,(n-1));
        }
        else
        {
            x = intpower(x,n/2);
            return  x*x;
        }
    
    }  
    
    或者你可以把你的功能减少到一行

    double intpower(double x, int n)
    {
        return n == 0 ? 1 : n%2 != 0 ? x*intpower( x, (n-1) ) : (x = intpower(x, n/2), x*x);
    }
    
    试试这个

    double intpower(double x, int n)
    {
        if(n == 0) return 1;
        if(n == 1) return x;
        if(n%2!=0)
        {
            return x*intpower(x,(n-1));
        }
        else
        {
            x = intpower(x,n/2);
            return  x*x;
        }
    
    }  
    
    或者你可以把你的功能减少到一行

    double intpower(double x, int n)
    {
        return n == 0 ? 1 : n%2 != 0 ? x*intpower( x, (n-1) ) : (x = intpower(x, n/2), x*x);
    }
    

    “oraz”(显然)对于我们这些不会说波兰语的人来说意味着“和”。是的,很抱歉:你使用的是
    int
    。您打算让
    intpower()
    处理负数吗?否则为什么不使用
    无符号
    ,或者至少说明限制?好的一点,这其实并不重要,更多的是关于算法和发生的乘法次数。但是算法选择受需求范围的影响。如果你不能清楚地表达你的需求,要么你得到的不是最佳结果,要么让其他人做不必要的工作。“oraz”(显然)的意思是“和”,对于我们这些不会说波兰语的人来说。是的,很抱歉:你使用的是
    int
    。您打算让
    intpower()
    处理负数吗?否则为什么不使用
    无符号
    ,或者至少说明限制?好的一点,这其实并不重要,更多的是关于算法和发生的乘法次数。但是算法选择受需求范围的影响。如果你没有清楚地表达你的需求,要么你得到的不是最佳结果,要么让其他人做不必要的工作。什么是“返回(k&1)?x*y*y:y*y;?你可以排除
    k==1
    检查。由于1是奇数,它将用
    x
    乘以
    int_pwr(x,0)
    的返回值,即1,得到正确的结果。这会在递归的每一次迭代中多做一次迭代,但每次迭代都少做一次检查,从长远来看,这通常是一次胜利。
    if(k%2==1){return x*y*y;}else{return y*y;}
    所以如果我理解正确,它的工作原理与我的算法完全相同?@pjs我意识到这一点,但OP说他必须使用给定的定义,所以我把它留在了。什么是“return(k&1)”的确切含义?x*y*y:y*y;?您可以排除
    k==1
    检查。因为1是奇数,所以它将乘以x