码迷,mamicode.com
首页 > 其他好文 > 详细

快速幂小结

时间:2017-08-23 10:23:14      阅读:126      评论:0      收藏:0      [点我收藏+]

标签:result   ==   奇数   代码   解释   理解   log   amp   取模运算   

(本文不涉及取模运算……)

快速幂,顾名思义,就是快速地求幂运算。

现在要求x=yn的值,最朴素的解法:

int pow(int y, int n) {
    int result = 1;
    for (int i = 0; i < n; i++) {
        result *= y;
    }
    return result;
}

复杂度是O(n)

 

当n是偶数的时候,我们设n=2*m,则x=yn=y2*m=(ym)^2

当n是奇数的时候,我们设n=2*m+1,则x=yn=y2*m+1=y*(ym)^2

这样,我们就把复杂度从O(n)降到了O(n/2),递归下去,算法的复杂度就是O(log2n)……该怎么解释这个……其实我不会……

用递归实现比较容易理解,具体代码:

int quick_pow(int y, int n) {
    if (n == 0) return 1;
    if (n % 2 == 1) {
        // n是奇数 n=2*m+1
        // x = y^(2*m+1) = y*(y^m)^2
        int m = n / 2;
        int temp = quick_pow(y, m);
        return y * temp *temp;
    } else {
        // n是偶数 n=2*m
        // x = y^(2*m) = (y^m)^2
        int m = n / 2;
        int temp = quick_pow(y, m);
        return temp *temp;
    }
}

可以简化一下~~

int quick_pow(int y, int n) {
    if (!n) return 1;
    int temp = quick_pow(y, n >> 1);
    if (n & 1) return y * temp *temp;
    else return temp *temp;
}

 

非递归的版本也很容易理解啦

int quick_pow(int y, int n) {
    int result = 1;
    while (n > 0) {
        if (n % 2 == 1) {
            // y^n = y^(2*m+1) = y*(y^2)^m
            result *= y;
            // 接下来让y=y^2, n=m
            y = y * y;
            n = n / 2;
        } else {
            // y^n = y^(2*m) = (y^2)^m
            y = y * y;
            n = n / 2;
        }
    }
    return result;
}

简化一下~~~

int quick_pow(int y, int n) {
    int result = 1;
    while (n) {
        if (n & 1) result *= y;
        y = y * y;
        n >>= 1;
    }
    return result;
}

 

矩阵快速幂

 

待续...

快速幂小结

标签:result   ==   奇数   代码   解释   理解   log   amp   取模运算   

原文地址:http://www.cnblogs.com/wenruo/p/7414964.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!