杂记——可能是最通俗易懂的快速幂

看到一道很简单的求整数次幂的题目,但是看到讨论区有用快速幂做的,我居然不知道这是什么?于是学之,记之(其实这玩意在大一的计算机导论里面提到过)

什么是快速幂

快速幂是一种简化运算底数的n次幂的算法,理论上其时间复杂度为 O(log₂N), 而一般的朴素算法则需要O(N)的时间复杂度。简单来说快速幂其实就是抽取了指数中的2的n次幂,将其转换为时间复杂度为O(1)的二进制移位运算,所以相应地,时间复杂度降低为O(log₂N)。

具体思路

首先以 b 13 b^{13} b13为例
可以把指数13用二进制表示,即为1101,将二进制数字1101直观地表现为十进制则是如下的等式:
13 = 1 ∗ 2 3 + 1 ∗ 2 2 + 0 ∗ 2 1 + 1 ∗ 2 0 13=1*2^3+1*2^2+0*2^1+1*2^0 13=123+122+021+120

这样一来,要求的结果可以如下算出:
b 13 = b 2 3 ∗ b 2 2 ∗ b 2 0 b^{13}=b^{2^3}*b^{2^2}*b^{2^0} b13=b23b22b20 或者 b 13 = b 2 3 ∗ b 2 2 ∗ ( 0 ∗ b 2 1 ) ∗ b 2 0 b^{13}=b^{2^3}*b^{2^2}*(0*b^{2^1})*b^{2^0} b13=b23b22(0b21)b20(把0补上便于理解)
四个项对应1101

如果更加直观地展现为快速幂的思想,应该这样写(实际上就是换了个写法然后把顺序也调换了一下,看不懂的可以复习下高一数学):
b 1 ∗ ( b 2 ) 2 ∗ ( ( b 2 ) 2 ) 2 b^1*{(b^2)}^2*{({(b^2)}^2)}^2 b1(b2)2((b2)2)2 或者 b 1 ∗ ( 0 ∗ b 2 ) ∗ ( b 2 ) 2 ∗ ( ( b 2 ) 2 ) 2 b^1*(0*b^2)*{(b^2)}^2*{({(b^2)}^2)}^2 b1(0b2)(b2)2((b2)2)2 (把0补上便于理解)
四个项1011(从右边读起,程序中每次循环了右移一位,并且读取末位)

这样一来,递归的模子就有了,代码也就不难写出来了,java代码:

public int testPosition(int base,int exponent) {
        int result = 1=;
        while (exponent!=0) {
            if ((exponent & 1)!=0) {
                result *= base;
            }
            base *= base;
            exponent >>= 1;
        }
        return result;
    }

写完,告辞!

你可能感兴趣的:(数据结构和算法)