快速幂
幂是一个很重要的东西
例如求x^y
本来我一直使用的是C里自带的pow函数,但是最近查了一下,发现这个函数是实数计算函数,而且是double类型,所以容易出现问题
因而我学习了一下关于幂运算的一些代码。
参考来源:http://baike.baidu.com/link?url=pr1C8vT8nXIO7rGCKwhmi0toms--7zmkhYEdLpk3ClesVsVjFSJ9QxsHKGyRX-9lyNvwaANF5vpXkMrbTi07SK
首先是常规求幂,好像这也是pow函数的计算方式
1 int pow1(int a,int b) 2 { 3 int r=1; 4 while(b--) 5 r*=a; 6 return r; 7 }
这个和pow不同就是支持的是int型数据,注意大小
其实我们想一想,每次我们都计算a*a*a*a ,其实我们可以令b=a*a 原式则为b*b,对于更高的幂数我们令c=b*b 则继续优化了时间
那么,我们可以得到二分求幂,其实这个算法已经够用了。
1 int pow2(int a,int b) 2 { 3 int r=1,base=a; 4 while(b!=0) 5 { 6 if(b%2) 7 r*=base; 8 base*=base; 9 b/=2; 10 }
当然我们也可以利用位运算来得到我们想要的结果,我们将b转化为二进制数,例如b=11 = 2³×1 + 2²×0 + 2¹×1 + 2º×1
我们所求问题就转化为
1 int pow4(int a,int b) 2 { 3 int r=1,base=a; 4 while(b!=0) 5 { 6 if(b&1) 7 r*=base; 8 base*=base; 9 b>>=1; 10 } 11 return r; 12 }
其实和二分求幂是一样的,只是优化了b%2和b/=2两个操作,毕竟计算机看二进制更快
快速幂
1 int pow3(int x,int n) 2 { 3 if(n==0) return 1; 4 else 5 { 6 while((n&1)==0) 7 { 8 n>>=1; 9 x*=x; 10 } 11 } 12 int result=x; 13 n>>=1; 14 while(n!=0) 15 { 16 x*=x; 17 if((n&1)!=0) 18 result*=x; 19 n>>=1; 20 } 21 return result; 22 }
最后一个算法还没怎么看懂,先用着了,搁置一下