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;
}
归纳定义是
#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的定义如上所述。归纳定义如下
#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