簡單易懂的快速冪取模算法


本文是上一篇文章《程序員必學:快速冪算法》的續集,上一篇文章詳細地介紹了快速冪算法,提供了遞歸、非遞歸的2種實現方案

拋出問題

請設計一個算法求x的y次冪模z的結果:(x ^ y) % z

  • x、y、z都是整數
  • z ≠ 0, y ≥ 0
  • x、y的絕對值可能很大,比如(1234 ^ 4567) % 30

思考

由於x、y的絕對值可能很大,x ^ y的結果可能會溢出。所以先求x ^ y,再對z取模,顯然是不現實的。

這里要借助模運算的一條運算規則

(a * b) % p = ((a % p) * (b % p)) % p

根據上面的推導,就可以很容易寫出代碼實現

遞歸實現

int powMod(int x, int y, int z) {
    if (y == 0) return 1 % z;
    int half = powMod(x, y >> 1, z);
    half = (half * half) % z;
    if ((y & 1) == 0) { // y是偶數
        return half;
    } else { // y是奇數
        return (half * (x % z)) % z;
    }
}

非遞歸實現

int powMod(int x, int y, int z) {
    int result = 1 % z;
    x %= z;
    while (y != 0) {
        if ((y & 1) == 1) {
            result = (result * x) % z;
        }
        x = (x * x) % z;
        y >>= 1;
    }
    return result;
}

測試用例

// 4
powMod(1234, 4567, 30);
// 699
powMod(123, 456, 789);

如果你特別希望我寫點什么方面的內容,也可以留言建議,謝謝。歡迎關注


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM