快速的求幂的方法原理:
以下以求a的b次方来介绍
把b转换成
二进制数。
该二进制数第i位的权为2^(i-1)
例如 a^11 = a^(2^0 + 2^1 + 2^3)
11的二进制是1011
11 = 2³×1 + 2²×0 + 2¹×1 + 2º×1
因此,我们将a¹¹转化为算a^2^0 * a^2^1 * a^2^3
以上的来自百度百科:http://baike.baidu.com/link?url=o1UFGS2CuuAsA_Zl0-Lnk7pL014TarHyS91iuhR2iYyhFUCAwPGYFc2aubL05CvpBjLLsIl10FnkULDpV2PI6q#reference-[1]-4533005-wrap
简单来说,就是指数的转换成二进制,基数 = 基数 * 底数,当指数二进制位为1时,则结果 = 基数 * 结果;
最后,结果就是我们想要的结果。
下面是代码:
# include <iostream>
# include <string>
using namespace std;
int main()
{
char *mult(char *a, char *b);
char r[10000], base[10000], c[10], *str1, *str2;
int i, j, k, a, b;
cin >> a >> b;
r[0] = '1'; r[1] = '\0'; //结果字符串为1,初始化
i = 0;
while(a) //将底数a转换成字符串,这个字符串的相反的
{
c[i] = a % 10 + '0';
a = a / 10;
i++;
}
k = 0;
for(j = i - 1; j >= 0; j--, k++) //将底数a的字符串倒置
base[k] = c[j]; //底数的字符串赋值到基数字符串
base[k] = '\0';
str1 = r, str2 = base;
while(b) //快速求幂方法,时间复杂度为log2(n)
{
if(b & 1)
{
str1 = mult(str1, str2); //结果为str1, 结果 * 基数
}
str2 = mult(str2, str2); //基数为str2, 基数 * 基数
b = b >> 1; //右移
}
cout << str1 << endl;
return 0;
}
char *mult(char *a, char *b) //大数的算法,很容易明白的
{
int length1, length2, i, j, *s;
length1 = strlen(a);
length2 = strlen(b);
s = new int[length1 + length2]; //申请数组的空间
for(i = 0; i < length1 + length2; i++)//初始化
s[i] = 0;
for(i = 0; i < length1; i++)
{
for(j = 0; j < length2; j++)
s[i + j + 1] += (a[i] - '0') * (b[j] - '0');
}
for(i = length1 + length2 - 1; i >= 0; i--) //进位
{
if(s[i] >= 10)
{
s[i - 1] += s[i] / 10;
s[i] %= 10;
}
}
i = 0;
while(!s[i])
i++;
for(j = 0; i < length1 + length2; i++, j++) //转换成字符,并覆盖到a数组
{
a[j] = s[i] + '0';
}
a[j] = '\0';
delete []s; //释放
return a;
}
这里我用的是大数,可以算很大的次方,数组开大点,就可以算更大的。
结果: