Mục tiêu của kỹ thuật lập trình• Mục tiêu cơ bản • Tổ chức dữ liệu phù hợp, sáng tạo trên những dữ liệu đã học • Định hướng tìm lời giải cho bài toán cơ bản • Để đạt được mục tiêu, chúng
Trang 1KỸ THUẬT LẬP TRÌNH
CƠ BẢN
Khoa Công nghệ thông tin Trường Đại học Ngoại ngữ - Tin học TP.HCM (HUFLIT)
Trang 3Nội dung
• Kỹ thuật vòng lặp không xác định
• Kỹ thuật prefix sums
• Kỹ thuật sliding window
• Kỹ thuật two pointers
• Kỹ thuật robot đi trên lưới
• Kỹ thuật stack và queue
Trang 5Mục tiêu của kỹ thuật lập trình
• Mục tiêu cơ bản
• Tổ chức dữ liệu phù hợp, sáng tạo trên những dữ liệu đã học
• Định hướng tìm lời giải cho bài toán cơ bản
• Để đạt được mục tiêu, chúng ta sẽ
• Khai thác các câu lệnh, các cấu trúc dữ liệu, hàm đã học
• Điều khiển được từng câu lệnh
• Hiểu rõ một số ứng dụng tiềm ẩn của cấu trúc dữ liệu đơn
Trang 6KỸ THUẬT GIÁ TRỊ LÍNH CANH
Trang 7Tính toán bằng vòng lặp
• Ý tưởng của tính toán bằng Vòng lặp
• Thực hiện nhiều lần cùng một tính toán
• Qua mỗi bước lặp, giá trị tính toán sẽ tiệm cận giá trị mục tiêu
for ( int i=0; i<n; i++) { // thực hiện tính toán }
while (điều kiện) { // thực hiện tính toán }
Trang 8Tính toán bằng vòng lặp
• Một số vấn đề phát sinh trong vòng lặp
• Điều khiển được số lần lặp
• Thu nhận giá trị (trạng thái) phát sinh trong vòng lặp
• Điều khiển số lần lặp: có 2 phương pháp
• Điều khiển số lần lặp dựa trên bộ đếm (counter)
Counter-controlled iteration
• Điều khiển số lần lặp dựa trên giá trị lính canh (sentinel value)
Trang 9Counter-controlled iteration
• Bài toán "điểm trung bình": Một lớp học có 10 sinh
viên làm một bài kiểm tra Điểm của các bài kiểm tra
có giá trị từ 0 đến 10 Hãy xác định điểm trung bình
của bài kiểm tra này
• Ý tưởng: Điểm trung bình = tổng điểm / số sinh viên
• Nhập mỗi điểm, lưu tổng các điểm nhập vào
• Thực hiện tính trung bình
• In kết quả
Trang 10int grade = Convert.ToInt32(Console.ReadLine());
total = total + grade;
}
double average = total / 10.0;
Console.Write(average);
Trang 11Counter-controlled iteration
• Các bước sử dụng Counter-controlled iteration
• Bước 1 Xác định số lần lặp tối đa
• Bước 2 Dùng một biến counter để đếm số lần lặp của vòng lặp
• Mẫu chương trình Counter-controlled iteration
Trang 12Counter-controlled iteration
• Vòng lặp for được thiết kế để triển khai
counter-controlled iteration hiệu quả
for ( int counter=0 ; counter <=maxLoop; counter +=1) {
}
Trang 13Sentinel-controlled iteration
• Bài toán "điểm trung bình": Phát triển ứng dụng tính
điểm trung bình với số lượng sinh viên tùy ý trong mỗi
lần chạy
int total=0;
int gradeCounter=1;
while (gradeCounter<=???) {
int grade = Convert.ToInt32(Console.ReadLine());
total = total + grade;
gradeCounter += 1;
}
double average = total / 10.0;
Console.Write(average);
Trang 14Sentinel-controlled iteration
• Giá trị lính canh
• Nhận xét
• Giá trị lính canh (sentinel): còn gọi là signal value, dummy value
• Giá trị lính canh không được trùng với dữ liệu của chương trình
• Tùy theo bài toán sẽ có cách chọn giá trị lính canh phù hợp
Giá trị lính canh (sentinel) là một giá trị đặc biệt (trong ngữ
cảnh cụ thể của thuật toán) được dùng để kết thúc một tiến
trình (vòng lặp/hàm đệ quy)
Trang 15Sentinel-controlled iteration
• Bài toán "điểm trung bình": Phát triển ứng dụng tính
điểm trung bình với số lượng sinh viên tùy ý trong mỗi
lần chạy
• Ý tưởng:
• Người dùng nhập tất cả các điểm số mong muốn
• Sau đó người dùng nhập sentinel value để xác nhận không
còn điểm để nhập
• Chương trình phát hiện giá trị sentinel người dùng đã nhập
• Chương trình tính điểm trung bình
Trang 17Sentinel-controlled iteration
• Nhận xét
• Giá trị sentinel: −𝟏𝟏
• Tiến trình sẽ dừng khi gặp giá trị lính canh
• Sentinel được dùng trong vòng lặp khi không thể xác định số
lần thực hiện
Trang 18Sentinel-controlled iteration
• Các bước sử dụng Sentinel-controlled iteration
• Bước 1 Xác định giá trị lính canh (không được lẫn lộn với giá
trị của dữ liệu chương trình)
• Bước 2 Mỗi lần lặp, kiểm tra giá trị lính canh, để xác định
vòng lặp kết thúc
• Mẫu chương trình Sentinel-controlled iteration
Trang 19Giá trị lính canh
• Giá trị lính canh với cấu trúc dữ liệu
• Cài đặt
Khi quyệt qua một cấu trúc dữ liệu, chúng ta có thể đặt
giá trị lính canh (sentinel) ở đầu hay ở cuối của cấu trúc
dữ liệu để yêu cầu vòng lặp tự động dừng khi đã duyệt
xong cấu trúc dữ liệu
Trang 20Giá trị lính canh
• Bài toán: Cho mảng số nguyên 𝑎𝑎 = 𝑎𝑎0, 𝑎𝑎1, … , 𝑎𝑎𝑛𝑛−1 , (1 ≤ 𝑛𝑛 ≤
108) và số nguyên 𝑥𝑥 Kiểm tra xem mảng 𝒂𝒂 có chứa giá trị 𝒙𝒙
không? Nếu có xuất ra "Yes", ngược lại xuất ra "No"
Trang 21Giá trị lính canh
• Một số giá trị lính canh phổ biến
• Ký tự NULL ('\0') được dùng để báo hiệu kết thúc chuỗi trong
ngôn ngữ C
• Giá trị null (trong C#) được dùng để chỉ kết thúc danh sách
liên kết (linked list) hay cấu trúc dữ liệu cây (tree)
• Giá trị âm dùng để chỉ kết thúc dãy số dương
Trang 22KỸ THUẬT ĐẶT BIẾN CỜ
Trang 23Vòng lặp và trạng thái
• Vòng lặp cơ bản
• Vòng lặp phát sinh ra các trạng thái (states)
for ( int i=0; i<n; i++) {
// thực hiện tính toán
}
while (điều kiện) { // thực hiện tính toán }
for/while ( ) {
if (điều kiện)
if (điều kiện)
Trang 24Vòng lặp và trạng thái
• Vấn đề
Sau khi một tiến trình được thực hiện (vòng
lặp/hàm)
Cần kiểm tra xem một trạng thái (hay điều kiện)
nào đó có xảy trong tiến trình đó hay không?
Trang 25Kỹ thuật đặt biến cờ
• Kỹ thuật cờ
• Miền giá trị của biến cờ
• True/False
• Hay miền giá trị tùy ý (tùy theo đặc điểm bài toán)
Cờ (flag) là một biến ghi nhận một tín hiệu (signal)
đã xảy ra trong một tiến trình (vòng lặp/hàm)
Trang 26Kỹ thuật đặt biến cờ
• Các bước sử dụng biến cờ
• Bước 1 Khai báo biến cờ
• Bước 2 Khởi tạo biến cờ trước tiến trình
• Bước 3 Kiểm tra trạng thái trong tiến trình và sửa lại biến cờ
• Bước 4 Kiểm tra biến cờ sau tiến trình
Trang 28Kỹ thuật đặt biến cờ
• Bài toán: Cho mảng số nguyên 𝑎𝑎 = 𝑎𝑎0, 𝑎𝑎1, … , 𝑎𝑎𝑛𝑛−1 , (1 ≤
𝑛𝑛 ≤ 108) và số nguyên 𝑥𝑥 Kiểm tra xem mảng 𝒂𝒂 có chứa giá trị
𝒙𝒙 không? Nếu có xuất ra "Yes", ngược lại xuất ra "No"
1 4 3 2 8 9 4 6
𝑥𝑥 = 9
𝑥𝑥 = 7 → 𝑥𝑥 không có trong 𝑎𝑎
Trang 30Kỹ thuật đặt biến cờ
int [] a = {4, 6, 8, 2, 5, 4, 4, 8};
int x = 2;
bool flag = false ;
for ( int i=0; i<a.Length; i++)
if (a[i] == x)
flag = true ;
if (flag) Console.Write("Yes");
else Console.Write("No");
Trang 31Kỹ thuật đặt biến cờ
• Cài đặt bằng một function
bool Contains( int [] a, int x) {
for ( int i=0; i<a.Length; i++)
if (a[i] == x)
return true ;
return false ; }
void OtherFunc() {
if (Contains(a, x) == true) Console.Write("Yes");
else Console.Write("No");
}
Trang 32Kỹ thuật đặt biến cờ
• Cài đặt bằng một function có flag
bool Contains( int [] a, int x) {
bool flag = false ;
for ( int i=0; i<a.Length; i++)
if (a[i] == x) flag = true ;
return flag ; }
void OtherFunc() {
bool flag = Contains(a, x);
Trang 33Kỹ thuật đặt biến cờ
• Nhận xét:
• Có thể kết thúc vòng lặp sớm bằng lệnh break
bool flag = false ;
for ( int i=0; i<a.Length; i++)
if (a[i] == x) { flag = true ;
break ; }
Trang 34
Kỹ thuật đặt biến cờ
• Nhận xét:
• Có thể kết thúc vòng lặp sớm bằng lệnh break
bool Contains( int [] a, int x) {
bool flag = false ;
for ( int i=0; i<a.Length; i++)
if (a[i] == x) {
flag = true ;
break ; }
Trang 35Kỹ thuật đặt biến cờ
• Nhận xét
• Có thể dùng biến cờ như biến lính canh: đặt biến cờ trong
điều kiện của vòng lặp
bool flag = false ;
for ( int i=0; i<a.Length && flag== false ; i++)
if (a[i] == x)
flag = true ; .
Trang 36Kỹ thuật đặt biến cờ
• Nhận xét
• Có thể dùng biến cờ như biến lính canh: đặt biến cờ trong
điều kiện của vòng lặp
}
Trang 37Bài tập
• Bài tập “Kiểm tra số nguyên tố”: Cho số nguyên
dương 𝑛𝑛 (1 ≤ 𝑛𝑛 ≤ 106) Viết hàm kiểm tra số 𝑛𝑛 có là
số nguyên tố hay không
• Input: 5
• Output: Yes
• Input: 8
• Output: No