Thực hành tìm kiếm nhị phân¶
Tóm lược nội dung
Bài này hướng dẫn cách giải một số bài toán liên quan đến thuật toán tìm kiếm nhị phân:
- Xác định vị trí xuất hiện đầu tiên và cuối cùng
- Kiểm tra số chính phương
Bài 1¶
Đề bài¶
Yêu cầu:
Áp dụng thuật toán tìm kiếm nhị phân, viết chương trình xác định vị trí xuất hiện đầu tiên và cuối cùng của một giá trị k trong mảng một chiều A đã có thứ tự tăng dần.
Đầu vào:
Mảng một chiều A tăng dần và giá trị k.
Đầu vào:
Vị trí bắt đầu và vị trí kết thúc.
Ví dụ:
| Đầu vào | Đầu ra |
|---|---|
| [0, 1, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 7, 8, 8, 9] 4 |
Vị trí bắt đầu: 3 Vị trí kết thúc: 12 |
Cách giải đề xuất¶
Ý tưởng chính
Đối với vị trí xuất hiện đầu tiên: khi tìm được giá trị k, ta không dừng lại như trong bài học, mà vẫn tiếp tục thực hiện tìm kiếm nhị phân đối với mảng con bên trái.
Nói cách khác, khi A[mid] == k, ta không return mid ngay, mà thay đổi mốc phải right để tiếp tục tìm kiếm trên mảng con bên trái, cho đến khi không thể chia đôi mảng được nữa.
Tương tự, đối với vị trí xuất hiện cuối cùng: khi A[mid] == k, ta không return mid ngay, mà thay đổi mốc trái left để tiếp tục tìm kiếm trên mảng con bên phải, cho đến khi không thể chia đôi mảng được nữa.
Viết chương trình
0. Nạp thư viện numpy.
1. Viết hàm find_first_occurrence() dùng để tìm vị trí xuất hiện đầu tiên.
Hàm gồm có:
- Hai tham số đầu vào là mảng
Atăng dần và giá trịk. - Giá trị trả về là vị trí đầu tiên tìm thấy.
Hàm hoạt động như sau:
- Khởi tạo biến
resultdùng để lưu vị trímidtìm thấyk. - Khi
A[mid] == kthì gánmidchoresultvà thay đổi mốc phải để tiếp tục tìm trên mảng con bên trái:right = mid - 1. - Trả về
result.
2. Viết hàm find_last_occurrence() dùng để tìm vị trí xuất hiện cuối cùng.
Hàm gồm có:
- Hai tham số đầu vào là mảng
Atăng dần và giá trịk. - Giá trị trả về là vị trí cuối cùng tìm thấy.
Hàm hoạt động như sau:
- Khởi tạo biến
resultdùng để lưu vị trímidtìm thấyk. - Khi
A[mid] == kthì gánmidchoresultvà thay đổi mốc trái để tiếp tục tìm trên mảng con bên phải:left = mid + 1. - Trả về
result.
3. Viết chương trình chính.
- Khởi tạo mảng
arr. - Cho người dùng nhập giá trị
key. - Gọi hàm
find_first_occurrence()ra thực hiện và gán kết quả trả về cho biếnfirst. - Gọi hàm
find_last_occurrence()ra thực hiện và gán kết quả trả về cho biếnlast. - In ra
firstvàlast.
Bài 2¶
Đề bài¶
Yêu cầu:
Áp dụng thuật toán tìm kiếm nhị phân, viết chương trình kiểm tra xem số nguyên dương \(n (n > 1)\) có phải là số chính phương không.
Đầu vào:
Số nguyên dương n.
Đầu ra:
Là số chính phương hoặc không.
Ví dụ:
| Đầu vào | Đầu ra |
|---|---|
| 81 | Là số chính phương |
| 82 | Không phải là số chính phương |
| 6241 | Là số chính phương |
Cách giải đề xuất¶
Ý tưởng chính
Nếu tồn tại một giá trị ở giữa \(mid\) sao cho \(mid^2\) bằng \(n\) thì \(n\) là số chính phương.
Ngược lại, không tồn tại \(mid\) thì \(n\) không phải là số chính phương.
Do đó, ta dùng thuật toán tìm kiếm nhị phân để tìm \(mid\) này.
Viết chương trình
1. Viết hàm is_square_number() để kiểm tra chính phương.
Hàm gồm có tham số n là số cần kiểm tra.
Giá trị trả về là i hoặc -1.
Hàm hoạt động như sau:
- Khởi tạo
left = 2vàright == n // 2 + 1 - Nếu
mid * mid == nthì trả vềmid. - Ngược lại, thay đổi mốc trái
lefthoặc mốc phảiright.
2. Viết chương trình chính.
- Gọi hàm
is_square_number()ra thực hiện và gán kết quả trả về cho biếns. - Dựa vào giá trị của
s, in ra thông báo là chính phương hoặc không.
Mã nguồn¶
Code đầy đủ được đặt tại: