Cet article est une suite de l' article précédent "Les programmeurs doivent apprendre: algorithme d'alimentation rapide ". L'article précédent a présenté en détail l'algorithme d'alimentation rapide, fournissant deux solutions d'implémentation récursive et non récursive
Lancer une question
Veuillez concevoir un algorithme pour trouver le résultat du module de puissance y z de x : (x ^ y)% z
- x, y, z sont tous des entiers
- z ≠ 0, y ≥ 0
- Les valeurs absolues de x et y peuvent être grandes, telles que (1234 ^ 4567)% 30
Penser
Étant donné que les valeurs absolues de x et y peuvent être grandes, le résultat de x ^ y peut déborder. Par conséquent, il est évidemment irréaliste de trouver d'abord x ^ y, puis de prendre le module de z.
Ici, nous devons utiliser une règle arithmétique de l'arithmétique modulaire
(a * b)% p = ( (a% p) * (b% p) ) % p
Selon la dérivation ci-dessus, vous pouvez facilement écrire du code pour atteindre
Implémentation récursive
int powMod(int x, int y, int z) {
if (y == 0) return 1 % z;
int half = powMod(x, y >> 1, z);
half *= half;
if ((y & 1) == 0) { // y是偶数
return half % z;
} else { // y是奇数
return (half * (x % z)) % z;
}
}
Implémentation non récursive
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;
}
Cas de test
public static void main(String[] args) {
// 4
System.out.println(powMod(1234, 4567, 30));
// 699
System.out.println(powMod2(123, 456, 789));
}
Si vous voulez particulièrement que j'écrive quelque chose, vous pouvez également laisser une suggestion, merci. Bienvenue attention