快速幂_算法分析

版权声明:本文为博主原创作品, 转载请注明出处! https://blog.csdn.net/solider98/article/details/83187392

快速幂是典型的基于位运算和递推思想的, 用于快速求解a^{b}(a, b均为非整数的)的算法, C++代码实现如下:

//返回a^b的结果, 要求a^b不超过long long能表示的最大正整数 
long long power(int a, int b){
	long long ans = 1, tmp = a;
	for(; b; b >>= 1, tmp *= tmp) if(b & 1) ans *= tmp;
	return ans;
} 

显然算法中的for循环执行次数为O(lg(b))次, 每次用时O(1), 因此用时O(lg(b)). 下面对算法的正确性给出形式化证明:

    当参数b为0时, for循环体不执行, 因此算法直接返回1, 算法正确, 对于b > 0的情形:约定b的最低位为第0位, 最高位为第k位, 第i位为c_{i}, 则参数b对应的二进制表示为c_{k}2^{k}+c_{k - 1}2^{k - 1}+...c_{0}2^{0}c_{k} = 1, c_{i}\in {0 ,1}, (i >= 0 且 i <= k - 1), 则a^{b} = a^{c_{k}2^{k}}\times ...\times a^{c_{0}2^{0}} 给出循环不变式如下:

    第1次for循环头检测之前b的最低位对应原始参数b的第0位, tmp = a * 2^{0}, ans = \prod a ^{c_{i}2^{i}}(0 =< i < 0), (当不存在i满足0 =< i < 0时, 规定ans = 1)

    假设在第m(m >= 1)次for循环头检测之前b的最低位对应原始参数b的第m - 1位, tmp = a * 2^{m - 1}, ans = \prod a ^{c_{i}2^{i}}(0 =< i < m - 1), 那么在第m次执行循环体时根据第4行右边if语句的作用可得: 在第m + 1次循环头检测之前有b的最低位对应原始参数b的第m位, tmp = a * 2^{m}, ans = \prod a ^{c_{i}2^{i}}(0 =< i < m), 根据数学归纳法得: 在第k + 2次循环头检测之前有b的最低位对应原始参数b的第k + 1位(该位为0), tmp = a * 2^{k + 1}, ans = \prod a ^{c_{i}2^{i}}(0 =< i < k + 1且c_{i}\neq 0 ), 显然此时的ans = a^{b}, 因此算法正确.

    综上述, 算法正确性得证

猜你喜欢

转载自blog.csdn.net/solider98/article/details/83187392