btvn.vn
Tìm kiếm Đăng nhập

ƯCLN theo thuật toán Euclid

Lưu trên thiết bị này
Chuyên đề lựa chọn CS: Đệ quy · Chọn bài khác

Giữ ƯCLN khi thay cặp số

Cho hai số nguyên không âm a, b, không đồng thời bằng 0. Nếu b=0 thì ƯCLN(a,0)=a. Nếu b>0, đặt r=a%b; ta có a=q×b+r. Nếu d là ước chung của a và b thì d cũng là ước của r; ngược lại, nếu d là ước chung của b và r thì d cũng là ước của a. Vì vậy hai cặp có cùng các ước chung: $$\operatorname{gcd}(a,b)=\operatorname{gcd}(b,a\bmod b).$$ Số dư luôn thỏa 0≤r<b, nên đối số thứ hai giảm tới 0.

Kiểm b bằng 0 trước khi lấy dư

```python def gcd(a, b): if b == 0: return a return gcd(b, a % b) ``` Cơ sở được đặt trước phép a%b để không chia cho 0. Với a=0, b>0, lời gọi tiếp là gcd(b,0) và trả b. Cặp (0,0) bị loại bởi điều kiện của bài toán, dù đoạn mã riêng lẻ vẫn có thể trả 0 khi bị gọi với cặp đó.

Theo dõi một cặp cụ thể

Với a=84, b=30: | Lời gọi | Số dư | Tiếp theo | |---|---|---| | gcd(84,30) | 24 | gcd(30,24) | | gcd(30,24) | 6 | gcd(24,6) | | gcd(24,6) | 0 | gcd(6,0) | | gcd(6,0) | Không tính | Trả 6 | Các lời gọi đang chờ đều trả lại cùng kết quả 6. Không nhầm số dư 0 ở bước cuối với giá trị ƯCLN.

Cùng quy tắc có thể viết bằng vòng lặp

Bản lặp giữ cùng hai số a,b. Cần lưu số dư trước khi đổi a: ```python def gcd_lap(a, b): while b != 0: r = a % b a = b b = r return a ``` Một cách khác là trừ số nhỏ khỏi số lớn cho tới khi hai số bằng nhau. **Bản trừ dưới đây yêu cầu a,b đều dương**: ```python def gcd_tru(a, b): if a == b: return a if a > b: return gcd_tru(a - b, b) return gcd_tru(a, b - a) ``` Với hai số dương khác nhau, tổng a+b giảm sau mỗi bước mà ƯCLN không đổi. Nếu gọi bản này với (0,6), phép trừ vẫn cho (0,6), nên không tiến tới cơ sở. Không dùng điều kiện đầu vào của bản Euclid cho bản trừ khi chưa bổ sung xử lí số 0.

Bài luyện

Theo bảng, gcd(84,30) trả về bao nhiêu?
Chọn một đáp án

Bài luyện

Trong hàm gcd dùng số dư, vì sao phải kiểm b==0 trước a%b?
Chọn một đáp án

Bài luyện

Với điều kiện đầu vào của bản Euclid, cặp nào hợp lệ và cho kết quả 6?
Chọn một đáp án

Bài luyện

Gọi bản gcd_tru trong bài với (0,6) sẽ vướng điều gì?
Chọn một đáp án

Đang học