Tìm ước chung lớn nhất của 2 số
Tìm ước chung lớn nhất của 2 số
Contents
Ước chung lớn nhất (GCD - Greatest Common Divisor) của 2 số nguyên \(a\) và \(b\) là số nguyên lớn nhất \(d\) thỏa mãn cả \(a\) và \(b\) đều chia hết cho \(d\).
Thuật toán trừ dần
Mã nguồn (C):
int gcd(int a, int b) {
while (a != b) {
if (a > b) a = a - b;
else b = b - a;
}
return a;
}
Thuật toán Euclide
Công thức
Công thức Euclide để tính ước chung lớn nhất:
\[gcd(a, 0) = a\] \[gcd(a, b) = gcd(b, a \bmod b)\]Trong đó \(a \bmod b\) là số dư khi chi \(a\) cho \(b\).
Cài đặt đệ qui (C)
int gcd(int a, int b) {
if (b == 0) return a;
return gcd(b, a % b);
}
Cài đặt không đệ qui (C)
int gcd(int a, int b) {
int tmp;
while(b != 0) {
tmp = a % b;
a = b;
b = tmp;
}
return a;
}
Thuật toán nhị phân (Binary GCD Algorithm)
Thuật toán gồm các bước như sau:
- Nếu
a = b
thìgcd(a, b) = a = b
. gcd(0, v) = v
,gcd(u, 0) = u
.- Nếu cả
u
vàv
đều chẵn thìgcd(u, v) = 2*gcd(u/2, v/2)
. - Nếu
u
chẵn vàv
lẻ thìgcd(u, v) = gcd(u/2, v)
. Tương tự, nếuu
lẻ vàv
chẵn thìgcd(u, v) = gcd(u, v/2)
. - Nếu cả
u
vàv
đều lẻ vàu > v
thìgcd(u, v) = gcd((u-v)/2, v)
. Và ngược lại. - Lặp lại các bước trên.
Độ phức tạp : \(O(\log(\max(u, v))^2)\)
Cài đặt đệ qui (C):
int gcd(int a, int b) {
if (a == b) return a;
else if (a == 0 || b == 0) return a | b;
else if (!(a&1) && !(b&1)) return gcd(a>>1, b>>1)<<1;
else if (!(a&1) && b&1) return gcd(a>>1, b);
else if (a&1 && !(b&1)) return gcd(a, b>>1);
else if (a > b) return gcd((a-b)/2, b);
else return gcd((b-a)/2, a);
}