快速幂函数(递归实现) 与 快速幂取模函数

使用递归调用来实现快速幂函数可以说是对快速幂函数最为高效的方法之一,一般可以满足对于算法的时间复杂度需求。(好像还有一种更为高效的实现算法,感兴趣的请自行查找)

先贴上代码:

#include<cstdio>
#include<iostream>
using namespace std;

int Quick_pow(int base,int n)
{
    if(n == 0) return 1;
    if(n == 1) return base;
    int res = Quick_pow(base, n>>1);
    res = res * res;
    if(n%2 == 1)  //n为奇数 if (n & 1)
        res = res*base;
    return res;
}
int main()
{
    int a=Quick_pow(2, 5);
    cout<< a <<endl;
    return 0;
}

/*
1.一般防止数据爆掉,会把base定义为double类型或者是更大
的数据存储类型,还有一般会把n定义为unsigned int类型,编写函数时,
应当根据实际需求改变。
2.n>>1表示n对应的二进制的值往右顺移一位;if(n%2==1)可以改写成if(n & 1);
效果等价。不懂怎么用的自行百度。

3.理解代码的关键在于n>>1,打个比方base=5,n=11;各自顺移一位如下:
(11)1011->(5)0101->(2)0010->(1)0001;
也就是交给递归循环的部分永远会"<="本体的一半,11只给5给子递归处理,5只给2;
这样的话对应代码的第10行,(5)^5处理完了之后,本体还剩有(5)^6;
然后就是res=res*res;((5)^5*(5)^5,)在之后的工作就简单了,判断指数是不是奇数,因为之前5的10次方
已经解决了,如果是奇数的话,那么只需要乘以一遍base就可以return了;
*/

可能注释解释的那么多一下子没看懂,没关系,多看几遍,自己推算一遍就好了,代码不可多背,要在理解的基础上再去记忆,这样才能牢固学到的知识;

接下来是快速幂取模函数:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;

ll quickpow(ll m,ll n,ll k)  //快速幂取模函数,m:底数:指数,k:取模数
{
    ll ans=1;          //结果数ans  
m=m%k; while(n > 0) //当指数大于0的时候就执行循环 { if(n&1) //跟if(n%2 == 1) 的效果一样 ans = (ans*m)%k; //消除指数为奇数的影响 n=n >> 1; //n的二进制数右移一位; m = (m*m) % k; // 因为指数右移,所以这一步要消除指数右移的影响 } return ans%k; } //其实快速幂取模跟快速幂函数相差无几,只是记得在关键步骤后面要对K取模,防止数据爆掉; int main() { ll n,k,m; while(cin>>m>>n>>k) { cout<< quickpow(m,n,k) <<endl; } return 0; }

多看多学,多读书  -- 2018/5/4

原文地址:https://www.cnblogs.com/myxdashuaige/p/8946231.html