美文网首页
快速幂算法

快速幂算法

作者: ABleaf | 来源:发表于2019-12-15 12:28 被阅读0次

    原理

    x^n = \begin{cases} {(x ^ \frac{n}{2})^2,} & 如果n是偶数\\ {x(x ^ \frac{n-1}{2})^2,} & 如果n是奇数\\ \end{cases}

    例子

    计算x^{13}
    \begin{aligned} x^{13} &= (x^6)^2 \times x \\ &= ((x^3)^2)^2 \times x\\ &= ((x^2\times x)^2)^2\times x \end{aligned}
    可以看到,原本需要12次乘法的计算,现在只需要5次乘法了。

    分析

    x的上标全写为二进制
    \begin{aligned} x^{1101} &= (x^{110})^2 \times x^1 \\ &= ((x^{11})^2 \times x^0)^2 \times x^1\\ &= (((x^{1})^2\times x^1)^2 \times x^0)^2\times x^1 \end{aligned}

    可以看到,完全展开之后,x的上标组成的二进制串正是n的二进制串。真正进行计算时,\times x^0 = \times 1可以省略。因此,用快速幂算法计算x^n时,需要进行L - 1次平方运算和C - 1次乘法运算,其中Ln的二进制位数,Cn的二进制中的1的个数。平方运算其实就是乘法运算,因此,需要进行的乘法运算次数总计为L + C - 2,介于1 \sim 2\log_2(n)之间。因此,快速幂算法的时间复杂度为
    T(n) = O(\log_2n)

    实现

    def exp1(x, n):
        if n == 0:
            return 1
        if n == 1:
            return x
        y = exp1(x, n>>1) ** 2
        if n & 0x1:
            y *= x
        return y
    

    测试

    快速幂算法还可以像下面这样表述,时间复杂度与上面的一致。不过测试表明,比上面的要慢。
    x^n = \begin{cases} {(x ^ 2)^\frac{n}{2},} & 如果n是偶数\\ {x(x ^ 2)^\frac{n-1}{2},} & 如果n是奇数\\ \end{cases}

    def exp2(x, n):
        if n == 0:
            return 1
        if n == 1:
            return x
        y = exp2(x*x, n>>1)
        if n & 0x1:
            y *= x
        return y
    
    两种快速幂算法的比较

    可以看到,尽管大数乘法并非O(1),快速幂算法依然要比普通算法快得多。

    相关文章

      网友评论

          本文标题:快速幂算法

          本文链接:https://www.haomeiwen.com/subject/llcknctx.html