求a的n次方的C语言的伪代码,【算法学习】计算n次方——变治法

在计算a^n次方时,先将n变一变,寻找新的计算路径,预处理就是变治法的根本!算法

若是单纯循环执行n次相乘,那么时间复杂度为O(n),n为指数;利用二进制幂大大改进效率。数组

利用二进制幂求解分两种方法:从左至右二进制幂 和 从右至左二进制幂。spa

从左至右二进制幂

变换:

code

a^n = a^(b[n]2^n + ... + b[0]2^0) == ((b[n]*2 + b[n-1])*X +  ....)2 + b[0]input

先求n的二进制串:it

如 5 -> 1 0 1, 那么b[2] = 1, b[1] =0, b[0] =1io

二进制求n的伪代码:

Horner(b[0...n], x)

k = b[n]

for i = n-1 downto 0 do

p = x*k + b[i]

return pclass

那么n用做a的指数时意义是什么样的呢:效率

a^p = a^1

for i = n - 1 downto 0 do

a^p = a^(2p+b[i])

循环

从右至左二进制幂

n变换方法:

a^n = a^(b[n]2^n + ... + b[0]2^0) == ((b[n]*2 + b[n-1])*X +  ....)2 + b[0]

而后从b[0] -> b[n]方向逐步求解

详细代码:

#include

#include

/*

* 返回number二进制串

*/

int GetBinArray(int number, int arr[], int size)

{

int idx = 0;

while (number > 0)

{

if (number & 1)

arr[idx++] = 1;

else

arr[idx++] = 0;

if (idx == size)

break;

number = number >> 1;

}

return idx;

}

/*

* a^n = a^(b[n]2^n + ... + b[0]2^0) = a^(b[n]2^n) * ... * a^b[0]

* b数组元素不是1就是0

*/

int Pow_Bin_RightToLeft(int number, int p)

{

if (p == 0)

return 1;

int size = sizeof(int)*8;

int *pint = (int *)malloc(size);

int length = GetBinArray(p, pint, size);

int idx;

int item = number;

int ret = 1;

for (idx = 0; idx < length; idx++)

{

if (pint[idx] == 1)

ret = ret * item;

item *= item;

}

free(pint);

return ret;

}

/*

* a^n = a^(b[n]2^n + ... + b[0]2^0) == ((b[n]*2 + b[n-1])*X + ....)2 + b[0]

* b数组元素不是1就是0

*/

int Pow_Bin_LeftToRight(int number, int p)

{

if (p == 0)

return 1;

int size = sizeof(int)*8;

int *pint = (int *)malloc(size);

int length = GetBinArray(p, pint, size);

int ret = number;

int idx;

for (idx = length-1-1; idx >= 0; --idx)

{

ret *= ret;

if(pint[idx] == 1)

ret *= number;

}

free(pint);

return ret;

}

int main(int argc, char *argv[])

{

printf("Please input number and pow:\n");

int number,p;

scanf("%d%d", &number, &p);

int ret = Pow_Bin_RightToLeft(number, p);

int ret1 = Pow_Bin_LeftToRight(number, p);

printf("Pow_Bin_RightToLeft: %d^%d == %d\n", number, p, ret);

printf("Pow_Bin_LeftToRight: %d^%d == %d\n", number, p, ret1);

main(0, NULL);

return 0;

}

两个算法时间复杂度均为logn.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值