本文是上一篇文章《程序員必學:快速冪算法》的續集,上一篇文章詳細地介紹了快速冪算法,提供了遞歸、非遞歸的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);
如果你特別希望我寫點什么方面的內容,也可以留言建議,謝謝。歡迎關注