本人电子系,只为一学生。心喜计算机,小编以怡情。
计算an % b,其中a,b和n都是32位的整数。
样例:
例如 2^31 % 3 = 2
例如 100^1000 % 1000 = 0
快速幂网上有资料,而且我看其他博主说这是RSA公钥的加密方法(神奇)。
总之做完后给我的感觉就像是数字信号处理中的FFT算法,也是用一半算出整体,总之是相当的神奇。
快速幂-百度百科
核心算式a^n%b=(a^p * a^q)%b 其中p+q=n
思路是求出a^1%b,保存在数组里,再求a^2%b,保存在数组里,在求
a^4%b,a^8%b………….
举个例子3^5%7
5分解成二进制表示为101
则3^5%7转变为了(3^4%7 * 3^1%7) %7
而括号里 3^4%7是不是很熟悉?幂次项4是二进制100,而3^1%7中为001
而3^4%7又可以分解为(3^2%7 * 3^2%7) %7
而3^2%7又可以分解为(3^1%7 * 3^1%7) %7
而 3^1%7已经算过保存到数组里了,直接调用便可
根据这种递推的关系很容易就写出代码了
public int fastPower(int a, int b, int n) {
// write your code here
//这一条是为了解决31,1,0这类数据
if(n==0&&b==1)return 0;
String temp=Integer.toBinaryString(n);
int len= temp.length();
//用数组保存数据
long []arr=new long[len+1];
if(n==1) return a%b;
arr[1]=a%b;
//依次算出其他的比如arr[2]=a^2%b,arr[3]=a^4%b,arr[4]=a^8%b....
for(int i=2;i<=len;i++)
{
arr[i]=(arr[i-1]*arr[i-1])%b;
}
long ret=1;
int count=len-1;
//然后根据二进制依次得到最终结果比如5为"101"
//只算出arr[1]*arr[3]%b便可
for(int i=1;i<=len;i++)
{
if(temp.charAt(count--)=='0')
continue;
ret=ret*arr[i]%b;
}
return (int )ret;
}