Professional Documents
Culture Documents
1
NỘI DUNG
Giới thiệu
Tìm kiếm tuần tự
Tìm kiếm nhị phân
2
GIỚI THIỆU
Bài toán tìm kiếm rất phổ biến
Đầu vào bài toán là các thông tin cần thiết và
đầu ra là lời giải tối ưu thỏa điều kiện ràng
buộc
Hai phương pháp tìm kiếm thông dụng là
tuần tự và nhị phân
Trong bài toán tìm kiếm gồm có:
◦ Không gian tìm kiếm/lời giải tập hợp các lời giải
tiềm năng
◦ Điều kiện ràng buộc
Không gian lời giải có thể là:
◦ Tường minh: ta chỉ cần tìm kiểm tra và chọn lựa
◦ Không tường minh: phải tạo ra để tiếp tục xử lý 3
GIỚI THIỆU
Quá trình chọn lời giải gồm các bước
◦ Bước 0: tạo ra ứng viên lời giải (nếu chưa có)
◦ Bước 1: Kiểm tra ứng viên lời giải có thỏa
điều kiện ràng buộc hay không
◦ Bước 2: Trong số các ứng viên lời giải thỏa
mãn, sẽ có các tiêu chí để chọn ra ứng viên lời
giải tối ưu
Ví dụ: Tìm giá trị chẵn lớn nhất trong
mảng a có n số nguyên phân biệt (n > 0)
◦ Không gian tìm kiếm: n phần tử
◦ Điều kiện ràng buộc: số chẵn
◦ Tiêu chí đánh giá: lớn nhất 4
TÌM KIẾM TUẦN TỰ
(Trên mảng một chiều)
Bài toán 1: Cho mảng a gồm n số nguyên.
Viết hàm xác định giá trị phần tử lớn nhất
1 int FindMaxValue(int a[], int n){
2 int res = a[0];
3 for(int i = 1; i < n; i++){
4 if(a[i] > res) res = a[i];
5 }
6 return res;
7 }
◦ Chi phí: May mắn cần duyệt một lần. Trung bình
duyệt n/2 và không may duyệt n phần tử O(n)
◦ Không gian tìm kiếm: {0, n – 1}
◦ Điều kiện rang buộc: giá trị bằng x
◦ Tiêu chí đánh giá: phần tử có chỉ số nhỏ nhất 6
TÌM KIẾM TUẦN TỰ
(Trên mảng một chiều)
Bài toán 3: Cho mảng a gồm n số nguyên. Viết
hàm tìm vị trí của số chính phương nhỏ nhất
1 bool iSquare(int number){ 8 if(iSquare(a[i]) && (idx==-1 || a[i]<lc){
2 int i = (int)sqrt((float)number); 9 lc = a[i];
3 return (i*i == number); 10 idx = i;
4 } 11 }
5 int IdxOfMinSquareNumber(int a[], int n){ 12 }
6 int idx = -1, lc = 0; 13 return idx;
7 for(int i = 0; i < n; i++){ 14 }
◦ Chi phí: duyệt n phần tử O(n)
◦ Không gian tìm kiếm: {0, n – 1}
◦ Điều kiện rang buộc: số chính phương
◦ Tiêu chí đánh giá: phần tử nhỏ nhất
7
TÌM KIẾM TUẦN TỰ
(Trên mảng một chiều)
Bài toán 4: Cho mảng a gồm n số nguyên dương.
Viết hàm tìm vị trí số nguyên tố lớn nhất
1 bool iSPrime(int number){ 8 int idxOfMaxPrime(int a[], int n){
2 if(number < 2) return false; 9 int idx = -1, lc = 0;
3 int n = (int)sqrt(number); 10 for(int i = 0; i < n; i++){
4 for(int i = 2; i <= n; i++) 11 if(iSPrime(a[i]) && a[i] > lc){
5 if(number % i == 0) return false; 12 lc = a[i]; idx = i;
6 return true; 13 }
7 } 14 }return idx;}
Bai1.docx
24
TÌM KIẾM NHỊ PHÂN
(Trên mảng hai chiều)
Bài toán 19: Cho mảng số nguyên a gồm m dòng, n cột. Mảng a có
tính chất là các số trên mỗi dòng sắp tăng dần. Hãy viết hàm kiểm
tra xem mảng a có phần tử nào có giá trị x hay không
1 bool search2D(int** a, int m, int n, int x){
2 int from, to, mid;
3 for(int i = 0; i < m; i++){
4 from = 0; to = n – 1; 4 7 9 21 lặp log24 lần
5 while(from <= to){ 7 9 11 43 lặp log24 lần
6 mid = (from + to)/2; 8 9 44 67 lặp log24 lần
6log24
7 if(a[i][mid] == x) return true; 1 3 4 6 lặp log24 lần
8 else{ 2 4 6 7 lặp log24 lần
9 if(a[i][mid] < x) from = mid + 1; 1 1 6 7 lặp log24 lần
10 else to = mid – 1;
11 }}}
12 return false; } 25
TÌM KIẾM NHỊ PHÂN
(Trên mảng hai chiều)
Bài toán 20: Cho mảng số nguyên a gồm m dòng, n
cột. Mảng a có tính chất là các số trên mỗi dòng sắp
tăng dần từ trái sang phải, tăng từ dưới lên trên theo
cột. Viết hàm kiểm tra xem mảng a có phần tử nào có
giá trị x hay không (ví dụ x = 14)
1 bool search2D(int** a, int m, int n, int x){ j
2 int i = 0, j = 0;
0 1 2 3 4
3 while(i < m && j < n){
i→ 0 7 12 16 20 95
4 if(a[i][j] == x) return true;
1 5 9 14 15 19
5 else{
2 3 5 7 9 11
6 if(a[i][j] < x) j++;
3 1 2 3 4 5
7 else i++;
8 }
Chi phí lặp cỡ O(m + n)
9 return false;
10 } 26