Bài tập 34-Thay thếký tự:Nhập vào một xâu, sau đó thay thếtất cảcác ký tựtrắng 
(chr(32)) bằng ký tự“_”. Kết quảin ra màn hình bằng hàm MsgBox. 
Bài tập 35-Cộng sốnguyên lớn:Viết chương trình cộng 2 sốnguyên dương lớn 
bất kỳvà in kết quảra màn hình. 
Bài tập 36-Ma trận số:Viết chương trình nhập vào một ma trận gồm m hàng và n 
cột. Sau đó tính tổng các phần tửdương, tổng các phần tửtrên 2 đường chéo chính. 
Bài tập 37- Kiểm tra "đường thẳng" trong ma trận:Nhập một ma trận vuông kích 
thước N x N. Ma trận này chỉchứa các số0 và 1. Hãy lập trình đểcho biết ma trận 
đó có ít nhất 5 phần tửthẳng hàng (ngang, dọc, chéo xuôi, chéo ngược) có cùng giá 
trịlà 1 hay không ? 
Bài tập 38- Mảng bản ghi:Viết chương trình nhập vào một danh sách cán bộ, sau 
đó sắp xếp danh sách cán bộtheo tuổi và lưu vào một tệp tên là Canbo.txt. Thông tin 
vềcán bộgồm: Họvà tên, Năm sinh, Quê quán, Hệsốlương
                
              
                                            
                                
            
 
            
                 37 trang
37 trang | 
Chia sẻ: maiphuongdc | Lượt xem: 2975 | Lượt tải: 1 
              
            Bạn đang xem trước 20 trang tài liệu Giáo trình Bài tập lập trình hướng sự kiện, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
guyªn tè !” 
 If KetQua = False Then MsgBox n & “ kh«ng ph¶i lµ sè nguyªn tè !” 
End Sub 
c. Ghi chú: 
• Để thoát vô điều kiện khỏi vòng lặp Do While…, Do…Loop While hay 
Do … Loop Until thì cần gọi lệnh Exit Do 
• Hàm Sqr(n) trong VB dùng để tính n (không phải là tính bình phương như 
trong một số ngôn ngữ lập trình khác – như Pascal). 
• Nếu công việc gì chỉ làm một lần (ví dụ thông báo kết quả như trên) thì 
“KHÔNG BAO GIỜ” được đặt trong vòng lặp mà phải đặt ở ngoài vòng lặp. Vì 
đặc điểm của vòng lặp là “lặp đi lặp lại” nhiều lần một công việc ! 
Bài tập 12 
a. Hướng dẫn: Giai thừa của số N được tính theo công thức N!=1.2.3…N-1.N. Để 
tính toán ta thực hiện nhân dồn các số i ( i = 1 ÷ N) vào kết quả. 
b. Chương trình mẫu: 
Private Sub Form_Load() 
 Dim n As Integer, i As Integer, KetQua As Long 
BÀI TẬP LẬP TRÌNH HƯỚNG SỰ KIỆN Biên soạn: Bộ môn CNPM–ĐHSPKT HY 2005 
 Trang 12
 '/// NhËp sè n, ®¶m b¶o 0<n<10 
 Do 
 n = InputBox("CÇn tÝnh giai thõa cña mÊy : ") 
 Loop Until (0 < n And n < 10) 
 '/// Sö dông vßng lÆp For 
 KetQua = 1 
 For i = 1 To n 
 KetQua = KetQua * i 
 Next 
 Debug.Print "KÕt qu¶ cña " & n & "! = " & KetQua 
 '/// Sö dông vßng lÆp Do While 
 KetQua = 1 
 i = 1 
 Do While i <= n 
 KetQua = KetQua * i 
 i = i + 1 
 Loop 
 Debug.Print "KÕt qu¶ cña " & n & "! = " & KetQua 
 '/// Sö dông vßng lÆp Do Until 
 KetQua = 1 
 i = 1 
 Do Until i > n 
 KetQua = KetQua * i 
 i = i + 1 
 Loop 
 Debug.Print "KÕt qu¶ cña " & n & "! = " & KetQua 
 '/// Sö dông vßng lÆp Do ... Loop While 
 i = 1 
 KetQua = 1 
 Do 
 KetQua = KetQua * i 
 i = i + 1 
 Loop While i <= n 
 Debug.Print "KÕt qu¶ cña " & n & "! = " & KetQua 
 '/// Sö dông vßng lÆp Do ... Loop Until 
 i = 1 
 KetQua = 1 
 Do 
 KetQua = KetQua * i 
 i = i + 1 
 Loop Until i > n 
 Debug.Print "KÕt qu¶ cña " & n & "! = " & KetQua 
End Sub 
c. Ghi chú: 
• Có thể tính N! bằng phương pháp đệ qui : GiaiThua = GiaiThua (n-1) * N. 
• Người ta đã chứng minh được rằng tất các cấu trúc lặp đều có thể viết tương 
đương theo các cấu trúc khác. 
• Trong VB có rất nhiều cấu trúc lặp, tuy nhiên chỉ cần thuộc 3 cấu trúc sau là đủ: 
o For … 
BÀI TẬP LẬP TRÌNH HƯỚNG SỰ KIỆN Biên soạn: Bộ môn CNPM–ĐHSPKT HY 2005 
 Trang 13
o Do 
……… 
Loop Until 
o Do While 
 …….. 
Loop 
• Cấu trúc Do While … Loop và Do Until …. Loop cùng có điểm 
giống nhau là kiểm tra điều kiện trước khi lặp (giống như cấu trúc While …do 
trong Pascal hay While trong C/C++) nhưng cấu trúc Do While … 
Loop chỉ lặp khi điều kiện vẫn đúng, còn cấu trúc Do Until …. 
Loop chỉ lặp khi điều kiện vẫn sai (Hay thoát nếu là đúng). 
• Cấu trúc Do … Loop While và cấu trúc Do … Loop Until cùng 
giống nhau là thực hiện lặp sau đó mới kiểm tra điều kiện (Giống cấu trúc 
Repeat … Until trong pascal hay do … While trong C/C++), nhưng cấu trúc 
Do … Loop While chỉ lặp nếu điều kiện vẫn còn đúng, trong khi đó cấu 
trúc Do … Loop Until chỉ lặp nếu biểu thức điều kiện vẫn còn sai (Hay 
nói cách khác là kết thúc lặp nếu điều kiện lặp là đúng) 
• Khi thực hành, không nhất thiết phải nhớ cả 4 kiểu lặp đã nêu ở trên mà bạn 
nên vận dụng thành thạo 3 cấu trúc lặp được khuyến cáo dùng là For, Do 
While và Do … Loop Until, vì 3 cấu trúc này tương tự như các cấu trúc lặp 
trong một số ngôn ngữ lập trình phổ biến khác (For,While…do,Repeat 
..Until). 
Bài tập 13 
a. Hướng dẫn: Ta có thổng S = S1 + S2 + S3, với S1, S2, S3 tương ứng với 3 tổng 
trên. Sử dụng vòng lặp để tính tổng của mỗi Si, sau đó cộng lại để được kết quả. 
b. Chương trình mẫu: 
Private Sub form_load() 
 Dim i As Integer 
 Dim Tong As Long 
 Dim S1 As Long, S2 As Long, S3 As Long 
 Tong = 0 ' §Çu tiªn do ch−a tÝnh nªn Tong b»ng 0 
S1 = 0 
S2 = 0 
S3 = 0 
'/// TÝnh tæng S1 
For i = 1 To 8 
 S1 = S1 + i ^ 2 
Next 
'/// TÝnh tæng S2 
For i = 100 To 200 
 S2 = S2 + i ^ 2 
Next 
'/// TÝnh tæng S3 
For i = 300 To 310 
 S3 = S3 + i ^ 2 
Next 
S = S1 + S2 + S3 
MsgBox "Tæng lµ : " & Tong, vbInformation, "Th«ng b¸o ..." 
End Sub 
BÀI TẬP LẬP TRÌNH HƯỚNG SỰ KIỆN Biên soạn: Bộ môn CNPM–ĐHSPKT HY 2005 
 Trang 14
Bài tập 14: 
a. Hướng dẫn: Công thức tính giai thừa của số N là: N! = 1.2.3…N-1.N, như vậy ở 
đây ta cần nhân liên tiếp các số i (i chạy từ 1 đến n) vào kết quả. Trong đó, giá trị 
khởi tạo cho kết quả là 1. Bài này có thể giải theo cách đệ qui hoặc không đệ qui. 
b. Chương trình mẫu 
Cách 1: Dùng vòng lặp (Không dùng đệ qui) 
Private Sub Form_Load() 
 Dim i As Integer, n As Integer 
 Dim KetQua As Long 
 '/// NhËp sè n (0<n<20) 
 Do 
 n = InputBox("NhËp sè N : ", "TÝnh giai thõa") 
 Loop Until (0 < n And n < 20) 
 KetQua = 1 
 For i = 1 To n 
 KetQua = KetQua * i 
 Next 
 MsgBox n & " ! bằng " & KetQua 
End Sub 
Cách 2: Dùng đệ qui 
'/// Hµm ®Ö qui tÝnh N ! 
Function GiaiThua(ByVal N As Integer) As Long 
 If N = 1 Then 
 GiaiThua = 1 
 Else 
 GiaiThua = GiaiThua(N - 1) * N 
 End If 
End Function 
Private Sub Form_Load() 
 Dim i As Integer, N As Integer 
 Dim KetQua As Long 
 '/// NhËp sè n (0<n<20) 
 Do 
 N = InputBox("NhËp sè N : ", "TÝnh giai thõa") 
 Loop Until (0 < N And N < 20) 
 MsgBox N & " ! bằng " & GiaiThua(N) 
End Sub 
BÀI TẬP LẬP TRÌNH HƯỚNG SỰ KIỆN Biên soạn: Bộ môn CNPM–ĐHSPKT HY 2005 
 Trang 15
Bài tập 15: 
a. Hướng dẫn: Với bài toán dạng tính tổng của một chuỗi số khi biết số hạng tổng 
quát Si, nói chung là đơn giản. Có thể thực hiện theo giải thuậ như sau: 
 S = 0 
 For i = i0 TO in 
 S = S + Si 
 Next 
Với mỗi dãy khác nhau thì giá trị i0, N, Si có thể khác nhau và cần phải xác định. 
- Giá trị i0 và N thường xác định bởi giải phương trình Si = S0 và Si = Sn 
- Số hạng tổng quát Si thường có thể nhìn thấy ngay trong đề bài. 
Trong bài này: 
- )1(* ++= iniSi 
- Xác định i0: Cho S0 = Si ⇔ 2*1 +n = )1(* ++ ini ⇒ i0=1 
- Xác định in: Cho Sn = Si ⇔ )1(* ++ nnn = )1(* ++ ini ⇒ in=n 
b. Chương trình mẫu: 
Private Sub Form_Load() 
 Dim S As Single, i As Integer, N As Integer 
 N = InputBox("NhËp sè N : ") 
 S = 0 
 For i = 1 To N 
 S = S + i * Sqr(N + (i + 1)) 
 Next 
 MsgBox "Tæng cña d·y ®· cho lµ : " & S 
End Sub 
Bài tập 16 
a. Hướng dẫn: Với các bài toán được định nghĩa theo kiểu đệ qui thì cách giải phù 
hợp và dễ nhất là theo giải thuật qui. Tuy nhiên, tốc độ bị chậm đáng kể khi số N lớn, 
ngoài ra còn có thể bị tràn Stack. 
b. Chương trình mẫu: 
'/// TÝnh d·y Fibonasi dïng §Ö qui 
Function Fib_Dequi(ByVal N As Integer) As Long 
 If N = 0 Or N = 1 Then Fib_Dequi = 1 
 If N > 1 Then Fib_Dequi = Fib_Dequi(N - 2) + Fib_Dequi(N - 1) 
End Function 
'/// TÝnh d·y Fibonasi KH¤NG dïng §Ö qui 
Function Fib_KhongDequi(ByVal N As Integer) As Long 
 Dim i As Integer 
 Dim F1 As Long, F2 As Long, KetQua As Long 
 F1 = 1 
 F2 = 1 
 KetQua = 1 
BÀI TẬP LẬP TRÌNH HƯỚNG SỰ KIỆN Biên soạn: Bộ môn CNPM–ĐHSPKT HY 2005 
 Trang 16
 i = 2 
 Do While i <= N 
 KetQua = F1 + F2 
 F1 = F2 
 F2 = KetQua 
 i = i + 1 
 Loop 
 Fib_KhongDequi = KetQua 
End Function 
'--------------------------------------------------------------------------------------------------------------------------- 
'/// Ch−¬ng tr×nh chÝnh 
Private Sub Form_Load() 
 MsgBox "Fib (30) = " & Fib_Deq ui(30) 
 MsgBox "Fib (30) = " & Fib_KhongDequi(30) 
End Sub 
Chú ý: Riêng với bài toán này, người ta còn có thể giải bằng phương pháp qui hoạch 
động (Dynamic Programming) rất đơn giản như sau: 
Function Fib_DynamicPrgramming(ByVal N As Integer) As Long 
 Dim i As Integer 
 Dim F(1000) As Long '/// B¶ng chøa gi¸ trÞ ®· tÝnh to¸n ®−îc ë b−íc trung gian 
 '/// §iÓm xuÊt ph¸t 
 F(0) = 1 
 F(1) = 1 
 For i = 2 To N 
 F(i) = F(i - 2) + F(i - 1) 
 Next 
 Fib_DynamicPrgramming = F(N) 
End Function 
Bài tập 17: 
a. Hướng dẫn: Để tìm ước số chung lớn nhất của 2 số nguyên a và b, người ta có 
thể dựa vào công thức Ơ-Le và cài đặt bằng vòng lặp hoặc đệ qui. Việc tìm ước số 
chung được ứng dụng vào tối giản phân số. 
b. Chương trình mẫu: 
'/// T×m USCLN kh«ng dïng ®Ö qui 
Function USCLN(a As Integer, b As Integer) As Integer 
 Dim Du As Integer 
 Du = a Mod b 
 Do While Du 0 
 a = b 
 b = Du 
 Du = a Mod b 
 Loop 
 USCLN = b 
End Function 
BÀI TẬP LẬP TRÌNH HƯỚNG SỰ KIỆN Biên soạn: Bộ môn CNPM–ĐHSPKT HY 2005 
 Trang 17
'/// T×m USCLN b»ng §Ö qui 
Function USCLN_Dequi(a As Integer, b As Integer) As Integer 
 If a Mod b = 0 Then 
 USCLN_Dequi = b 
 Else 
 USCLN_Dequi = USCLN_Dequi(b, a Mod b) 
 End If 
End Function 
'----------------------------------------------------------------------------------------------------------------------------- 
'/// Ch−¬ng tr×nh chÝnh 
Private Sub Form_Load() 
 MsgBox "−íc sè chung lín nhÊt cña 20 vµ 30 lµ : " & USCLN(20, 30) 
 MsgBox "−íc sè chung lín nhÊt cña 20 vµ 30 lµ : " & USCLN_Dequi(20, 30) 
End Sub 
Bài tập 18: 
a. Hướng dẫn: Phân số dạng a/b được gọi là tối giản nếu Ước số chung lớn nhất của 
a và b là 1. Ví dụ: phân số 5/7 và 9/7 là tối giản; 4/6 và 6/4 là chưa tối giản. 
b. Chương trình mẫu: 
'/// T×m −íc sè chung lín nhÊt cña 2 sè a vµ b 
Function USCLN(a As Integer, b As Integer) As Integer 
 If a Mod b = 0 Then 
 USCLN = b 
 Else 
 USCLN = USCLN(b, a Mod b) 
 End If 
End Function 
'----------------------------------------------------------------------------------------------------------------------------- 
'/// Ch−¬ng tr×nh chÝnh 
Private Sub Form_Load() 
 Dim a As Integer, b As Integer, TuMoi As Integer, MauMoi As Integer 
 a = InputBox("NhËp tö sè : ") 
 b = InputBox("NhËp mÉu sè : ") 
 If USCLN(a, b) = 1 Then 
 MsgBox "Ph©n sè " & a & "/" & b & " ®· tèi gi¶n", vbInformation 
 Else 
 TuMoi = a / USCLN(a, b) ‘/// TÝnh l¹i tö sè míi 
 MauMoi = b / USCLN(a, b) ‘/// TÝnh l¹i mÉu sè míi 
 MsgBox "Ph©n sè sau khi tèi gi¶n lµ : " & TuMoi & "/" & MauMoi 
 End If 
End Sub 
Bài tập 19: 
a. Hướng dẫn: Trước hết cần xây dựng hàm kiểm tra xem số N có phải là nguyên tố 
hay không ? Sau đó sử dụng kết quả này vào giải quyết yêu cầu bài toán. 
b. Chương trình mẫu: 
BÀI TẬP LẬP TRÌNH HƯỚNG SỰ KIỆN Biên soạn: Bộ môn CNPM–ĐHSPKT HY 2005 
 Trang 18
'/// Hµm kiÓm tra xem sè N cã ph¶i lµ sè nguyªn tè hay kh«ng ? 
Function LaSoNguyenTo(ByVal n As Integer) As Boolean 
 Dim i As Integer 
 LaSoNguyenTo = True 
 For i = 2 To Round(Sqr(n)) 
 If n Mod i = 0 Then 
 LaSoNguyenTo = False 
 Exit Function 
 End If 
 Next 
End Function 
'----------------------------------------------------------------------------------------------------------------------------- 
'/// Ch−¬ng tr×nh chÝnh 
Private Sub Form_Load() 
 Dim i As Integer, n As Integer, DaySo(100) As Integer 
 n = InputBox("Sè phÇn tö cÇn nhËp : ", , 10) 
 For i = 1 To n 
 DaySo(i) = InputBox("NhËp sè thø " & i) 
 Next 
 For i = 1 To n 
 If LaSoNguyenTo(DaySo(i)) Then Debug.Print DaySo(i) 
 Next 
End Sub 
Bài tập 20 
a. Hướng dẫn: 
Để đếm số ký tự a và A trong một xâu S, chúng ta cần duyệt và kiểm tra lần lượt 
từng ký tự nằm trong xâu S và so sánh với ký tự a và A. Để duyệt (lấy từng ký tự 
trong xâu S) chúng ta có thể sử dụng một trong 3 loại vòng lặp. Hàm Mid(S,i,1) cho 
ta ký tự tại vị trí thứ i trong xâu S. 
b. Chương trình mẫu (Sử dụng vòng lặp Do While): 
Form_load() 
 Dim S As String 
 Dim TongAa As Integer 
 Dim i As Integer 
 S = InputBox("B¹n h·y nhËp mét x©u : ") 
 i = 1 'B¾t ®Çu tõ ký tù thø nhÊt 
 TongAa = 0 'Khëi t¹o sè ký tù A hoa vµ a th−êng ban ®Çu b»ng 0. 
 Do While i <= Len(S) 
 If Mid(S, i, 1) = "A" Or Mid(S, i, 1) = "a" Then 
 TongAa = TongAa + 1 
 End If 
 i = i + 1 ‘/// Chuyển đến vị trí của ký tự tiếp theo 
 Loop 
 MsgBox "Tæng sè ký tù a vµ A trong x©u lµ " & TongAa & " ký tù" 
End Sub 
BÀI TẬP LẬP TRÌNH HƯỚNG SỰ KIỆN Biên soạn: Bộ môn CNPM–ĐHSPKT HY 2005 
 Trang 19
C. Ghi chú: Trong vòng lặp For thì biến chạy sẽ được tự động tăng lên 1 đơn vị, còn 
trong vòng lặp Do While ... Loop và Do...Loop biến chạy không tự động tăng lên 1, 
do vậy ta phải tự thực hiện tăng biến chạy lên 1 đơn vị bằng câu lệnh i = i + 1 như 
bài tập ở trên. 
Bài tập 21: 
a. Hướng dẫn: Tổng S chính là tổng của các số hạng thứ i, với Si = ni
xi
+ (Đây là số 
hạng tổng quát) và i chạy từ 0 đến N. Do vậy để tính tổng chúng ta cần sử dụng một 
trong 3 loại vòng lặp đã học. 
b. Chương trình mẫu: (Sử dụng vòng lặp For, bạn hãy thực hiện với vòng lặp 
do...While và do...Loop) 
Private Sub Form_Load() 
 Dim i As Integer, N As Integer, x As Single 
 Dim S As Single 
 '///////// NhËp x vµ n //////////////////////// 
 x = InputBox("NhËp vµo sè x : ") 
 N = InputBox("NhËp vµo sè n : ") 
 S = 0 '// Khëi t¹o tæng S = 0 
 For i = 0 To N 
 S = S + x ^ i / (i + 1) ‘/// Nói chung là : S = S + 
 Next 
 MsgBox "Tæng S = " & S, vbInformation, "TÝnh tæng chuçi" 
End Sub 
Chú ý: Khi tính tổng của một dãy số bất kỳ, việc khó khăn nhất là phải xác định được 
số hạng tổng quát Si, sau đó là cận dưới và cận trên của vòng lặp. Còn tổng thì 
thường tính theo công thức : S = S + Si 
Bài tập 22 
a. Hướng dẫn: Trước hết cần khai báo một mảng nguyên, sau đó hỏi người dùng 
xem muốn nhập bao nhiêu số và sử dụng vòng lặp để tiến hành nhập dữ liệu cho 
mảng. 
Để tìm số lớn nhất, thông thường ta giả định là phần tử đầu tiên. Sau đó dùng vòng 
lặp để duyệt qua các phần tử còn lại và so sánh, nếu số đang xét lớn hơn số giả định 
thì ta lại thay đổi giá trị của số giả định bằng phần tử đang xét. 
b. Chương trình mẫu: 
Private Sub Form_Load() 
 Dim i As Integer, N As Integer 
 Dim MAX As Integer 
 Dim A(100) As Integer 'Khai b¸o m¶ng A cã 101 phÇn tö 
 '///////// NhËp sè phÇn tö n 
 N = InputBox("B¹n cÇn nhËp bao nhiªu sè: ") 
BÀI TẬP LẬP TRÌNH HƯỚNG SỰ KIỆN Biên soạn: Bộ môn CNPM–ĐHSPKT HY 2005 
 Trang 20
 For i = 1 To N 
 A(i) = InputBox("NhËp vµo sè thø " & i) 
 Next 
 '/////// T×m sè lín nhÊt trong N sè võa nhËp /////////////////////// 
 MAX = A(1) '///Gi¶ ®Þnh phÇn tö lín nhÊt lµ phÇn tö A(1) 
 For i = 1 To N 
 If A(i) > MAX Then MAX = A(i) 
 Next 
 MsgBox "PhÇn tö lín nhÊt lµ : " & MAX 
End Sub 
C. Ghi chú: ở trên chúng ta đã khai báo mảng A(100) và như vậy phần tử đầu tiên là 
A(0), nhưng khi nhập ta lại cho i chạy từ 1, tức là không sử dụng phần tử A(0). Đây 
là thói quen sử dụng của mỗi người. Bạn có thể sử dụng A(0) hay không là tuỳ, còn 
nếu sử dụng A(0) thì vòng lặp trên sẽ có dạng : For i= 0 to N - 1 .... 
Bài tập 23 
a. Hướng dẫn: Cần phải tìm ra số lớn nhất, kí hiệu là MAX, sau đó hiển thị những 
phần tử có giá trị bằng với MAX vừa tìm được. 
b. Chương trình mẫu: 
Private Sub Form_Load() 
 Dim i As Integer, MAX As Integer 
 Dim DS(100) As Integer, N As Integer 
 '/// NhËp c¸c sè 
 N = InputBox("NhËp sè phÇn tö : ") 
 For i = 1 To N 
 DS(i) = InputBox("NhËp sè thø " & i) 
 Next 
 '/// T×m sè lín nhÊt c¸c sè võa nhËp 
 MAX = DS(1) 
 For i = 1 To N 
 If MAX < DS(i) Then MAX = DS(i) 
 Next 
 '/// HiÓn thÞ nh÷ng phÇn tö b»ng víi MAX (chÝnh lµ nh÷ng ptö lín nhÊt) 
 For i = 1 To N 
 If DS(i) = MAX Then Debug.Print DS(i) 
 Next 
End Sub 
C. Ghi chú: 
• Có thể áp dụng để giải bài toán tìm số nhỏ nhất, in ra các số nhỏ nhất v.v… 
• Trong danh sách không phải chỉ có duy nhất một phần tử lớn nhất (nhỏ nhất) 
Bài tập 24 
a. Hướng dẫn: 
Để sắp xếp một dãy số A có N phần tử ta tiến hành như sau: 
• Bắt đầu từ phần tử đầu tiên 
BÀI TẬP LẬP TRÌNH HƯỚNG SỰ KIỆN Biên soạn: Bộ môn CNPM–ĐHSPKT HY 2005 
 Trang 21
• Tại vị trí (phần tử) thứ i trong mảng A, Ta xét tất cả các số từ thứ i+1 đến N 
xem có số nào nhỏ hơn phần tử thứ i đang xét hay không. Nếu có phần tử A(j) 
nào đó nhỏ hơn A(i) thì hoán đổi giá trị của A(i) Cho A(j). Để hoán đổi A(i) với 
A(j) ta thực hiện như sau: 
o TrungGian = A(i) 
o A(i) = A(j) 
o A(j) = TrungGian 
• Lặp lại đối với các phần tử A(i) cho đến khi nào i >= N thì dừng. 
b. Chương trình mẫu: 
Private Sub Form_Load() 
 Dim i As Integer, N As Integer, TrungGian As Integer 
 Dim A(100) As Integer 'Khai b¸o m¶ng A cã 101 phÇn tö 
 '///////// NhËp sè phÇn tö N vµ nhËp d÷ liÖu cho m¶ng A 
 N = InputBox("B¹n cÇn nhËp bao nhiªu sè: ") 
 For i = 1 To N 
 A(i) = InputBox("NhËp vµo sè thø " & i) 
 Next 
 '/////// S¾p xÕp m¶ng A theo chiÒu t¨ng dÇn /////////////////////// 
 For i = 1 To N - 1 '///DuyÖt tõng phÇn tö tõ 1 ®Õn N-1 
 For j = i + 1 To N '///KiÓm tra c¸c phÇn tö cßn l¹i ®øng sau phÇn tö thø i 
 If A(j) < A(i) Then '///Nếu nhỏ hơn số i thi` Ho¸n ®æi A(i) víi A(j) 
 TrungGian = A(i) 
 A(i) = A(j) 
 A(j) = TrungGian 
 End If 
 Next 
 Next 
 Debug.Print "D·y sau khi s¾p xÕp " 
 For i = 1 To N 
 Debug.Print A(i) 
 Next 
End Sub 
Chú ý: 
• Thuật toán sắp xếp ở trên thường xuyên được sử dụng trong các bài toán 
không đòi hỏi nhiều về tốc độ và nó có thể áp dụng để sắp xếp một danh sách 
tổng quát (cả số và xâu), do vậy chúng ta cần nắm vững thuật toán này. 
• Nếu muốn sắp xếp danh sách theo chiều giảm dần thì chỉ việc thay câu lệnh 
If A(j) A(i) Then …. 
Bài tập 25 
a. Hướng dẫn: Về bản chất, giải thuật Quick_Sort sử dụng phương pháp “Chia để trị” 
(Deive and Conquer). Có thể mô tả thô thuật toán này như sau: 
- Chọn một vị trí K ở giữa (Không nhất thiết là chính giữa) của danh sách L. 
- Duyệt từng phần tử và xét: Nếu phần tử L[i] < L[k] thì cho vào danh sách con 
L1, còn nếu L[i] >= L[k] thì cho vào danh sách L2. Kết quả ta được: 
L = L1 ∪ L[k] ∪ L2, Trong đó L[k] ở vị trí đúng. Tiếp tục thực hiện đệ qui với L1 
và L2… Do L hữu hạn nên thuật toán sẽ dừng. Độ phức tạp của thuật toán 
này trung bình vào cỡ O(n) = n.Log2n. 
BÀI TẬP LẬP TRÌNH HƯỚNG SỰ KIỆN Biên soạn: Bộ môn CNPM–ĐHSPKT HY 2005 
 Trang 22
b. Chương trình mẫu: 
'/// Thñ tôc t¸ch danh s¸ch thµnh 2 danh s¸ch con vµ 1 vÞ trÝ ®óng (Chèt-K) 
Sub TachDanhSach(DS() As Integer, ByVal L As Integer, ByVal R As Integer, K As Integer) 
 Dim i As Integer, j As Integer, Tam As Integer 
 i = L 
 j = R 
 Do While i < j 
 Do While DS(j) > DS(i) 
 j = j - 1 
 Loop 
 Do While (DS(i) <= DS(L)) And (i < j) 
 i = i + 1 
 Loop 
 If (j > i) Then 
 Tam = DS(i) 
 DS(i) = DS(j) 
 DS(j) = Tam 
 End If 
 Loop 
 K = j 
 Tam = DS(L) 
 DS(L) = DS(j) 
 DS(j) = Tam 
End Sub 
'----------------------------------------------------------------------------------------------------------------------------- 
'/// Thùc hiÖn s¾p xÕp Quick_Sort 
Private Sub Quick_Sort(ByRef DS() As Integer, ByVal L As Integer, ByVal R As Integer) 
 Dim K As Integer 
 If R > L Then 
 TachDanhSach DS, L, R, K 
 Quick_Sort DS, L, K - 1 
 Quick_Sort DS, K + 1, R 
 End If 
End Sub 
'----------------------------------------------------------------------------------------------------------------------------- 
'/// Ch−¬ng tr×nh chÝnh 
Private Sub Form_Load() 
 Dim i As Integer, n As Integer, DaySo(100) As Integer 
 n = InputBox("Sè phÇn tö cÇn nhËp : ", , 10) 
 For i = 1 To n 
 DaySo(i) = InputBox("NhËp sè thø " & i) 
 Next 
 Debug.Print "D·y sè sau khi s¾p xÕp lµ : " & vbCrLf 
 Quick_Sort DaySo, 1, n 
 For i = 1 To n 
 Debug.Print DaySo(i) 
 Next 
End Sub 
BÀI TẬP LẬP TRÌNH HƯỚNG SỰ KIỆN Biên soạn: Bộ môn CNPM–ĐHSPKT HY 2005 
 Trang 23
c. Ghi chú: 
• Trong phần khai báo hàm và thủ tục, nếu trước tham số hình thức không có 
từ khoá byref đứng trước thì VB hiểu đó là tham biến (tham chiếu). 
• Tham số hình thức trong phần khai báo chương trình con là một mảng thì phải 
viết dưới dạng như sau: () As , Cách viết: A (10) As 
integer hay A (1 to 10) As String v.v… là sai !. 
• Giải thuật Quick_Sort thực hiện tương đối nhanh khi n lớn. Người ta gọi giải 
thuật sắp xếp Quick_Sort và một số giải thuật sắp xếp nhanh khác (như 
Merge sort, Heap sort…) thuộc phương pháp sắp “Công nghiệp”, do vậy cần 
phải nhớ và vận dụng thành thạo giải thuật này. 
Bài tập 26 
a. Hướng dẫn: Ý tưởng của giải thuật này là dùng mảng một chiều để biểu diễn cây 
nhị phân. Sau đó tinh chỉnh dần các cây con đã được sắp xếp để cho kết quả cuối 
cùng. 
b. Chương trình mẫu 
'/// Thñ tôc ho¸n ®æi gi¸ trÞ cña 2 biÕn a vµ b cho nhau (sÏ sử dông trong ch−¬ng tr×nh) 
Sub Swap(a As Integer, b As Integer) 
 Dim Tam As Integer 
 Tam = a 
 a = b 
 b = Tam 
End Sub 
'----------------------------------------------------------------------------------------------------------------------------- 
'/// Thñ tôc ®iÒu chØnh l¹i c©y con b¾t ®Çu tõ nót i ®Ó nã trë thµnh mét ®èng (Heap) 
'/// §iÒu chØnh t¹i nót i cña c©y DS, cã N phÇn tö 
Sub DieuChinhNut(i As Integer, N As Integer, DS() As Integer) 
 Dim R As Integer 
 If i > (N \ 2) Then Exit Sub 
 '/// So s¸nh con tr¸i vµ con ph¶i cña nót i, nÕu con nµo lín h¬n th× 
 '/// R sÏ l−u vÞ trÝ cña con ®ã 
 R = 2 * i '/// Gi¶ sö con tr¸i lín h¬n 
 If (R + 1 <= N) And (DS(R) < DS(R + 1)) Then R = R + 1 
 If DS(i) < DS(R) Then '//NÕu nót cha i nhá h¬n th× tr¸o ®æi l¹i gi¸ trÞ ®Ó tho¶ m·n lµ Heap 
 Call Swap(DS(i), DS(R)) 
 Call DieuChinhNut(R, N, DS) '/// cÇn ph¶i ®iÒu chØnh l¹i nót R sau khi ho¸n ®æi 
 End If 
End Sub 
'----------------------------------------------------------------------------------------------------------------------------- 
'/// ®iÒu chØnh toµn bé N nót cña c©y (Danh s¸ch) ®Ó toµn bé c©y tho¶ m·n lµ Khèi Heap 
Sub DieuChinhToanBo(N As Integer, DS() As Integer) 
 Dim i As Integer 
 For i = N \ 2 To 1 Step -1 
 Call DieuChinhNut(i, N, DS) 
 Next 
End Sub 
BÀI TẬP LẬP TRÌNH HƯỚNG SỰ KIỆN Biên soạn: Bộ môn CNPM–ĐHSPKT HY 2005 
 Trang 24
'/// Thùc hiÖn HeapSort 
Sub Heap_Sort(N As Integer, DS() As Integer) 
 Dim i As Integer 
 DieuChinhToanBo N, DS 
 For i = N To 2 Step -1 
 Swap DS(1), DS(i) 
 DieuChinhNut 1, i - 1, DS 
 Next 
End Sub 
'----------------------------------------------------------------------------------------------------------------------------- 
'/// Ch−¬ng tr×nh chÝnh 
Private Sub Form_Load() 
 Dim i As Integer, N As Integer, DaySo(100) As Integer 
 N = InputBox("Sè phÇn tö cÇn nhËp : ", , 10) 
 For i = 1 To N 
 DaySo(i) = InputBox("NhËp sè thø " & i) 
 Next 
 Debug.Print "D·y sè sau khi s¾p xÕp lµ : " & vbCrLf 
 Heap_Sort N, DaySo 
 For i = 1 To N 
 Debug.Print DaySo(i) 
 Next 
End Sub 
c. Ghi chú: 
• Toán tử “\” để thực hiện phép chia lấy phần nguyên. 
• Khi gọi hàm hay thủ tục có thể thêm từ khoá Call hoặc không, nhưng khi có từ 
khoá Call thì các tham số phải được đặt trong ngoặc đơn như trên. 
• Một cây nhị phân có thể biểu diễn bằng mảng một chiều, trong đó nút con trái 
của nút i có chỉ số là i*2 và nút con phải là i*2 + 1. Nút cha của nút i có chỉ số 
là i \ 2. 
Bài tập 27 
a. Hướng dẫn: Việc sắp xếp có thể thực hiện thông qua giải thuật sắp xếp đơn giản 
có độ phức tạp tính toán n2. (Áp dụng thuật toán đã sử dụng trong bài tập 12) 
b. Chương trình mẫu: 
Private Sub Form_Load() 
 Dim DanhSach(100) As String ‘// Mảng lưu danh sách tên của lớp 
 Dim SoSV As Integer '//Số Sinh viên nhập vào 
 Dim i As Integer 
 SoPT = InputBox("Bạn cần nhập tên của bao nhiêu người : ") 
 For i = 1 To SoSV 
 DanhSach(i) = InputBox("Nhập tên của người thứ " & i) 
 Next 
 Dim j As Integer, TrungGian As String 
 '/// Sắp xếp tăng dần bằng 1 thuật toán đơn giản (dùng với số pt ít) 
BÀI TẬP LẬP TRÌNH HƯỚNG SỰ KIỆN Biên soạn: Bộ môn CNPM–ĐHSPKT HY 2005 
 Trang 25
 For i = 1 To SoSV- 1 
 For j = i + 1 To SoSV 
 If DanhSach(j) < DanhSach(i) Then 
 TrungGian = DanhSach(i) 
 DanhSach(i) = DanhSach(j) 
 DanhSach(j) = TrungGian 
 End If 
 Next 
 Next 
 '/// Hiển thị danh sách vừa sắp xếp ra cửa sổ Immediate 
 '/// Nhấn Ctrl-G để hiển thị cửa sổ này 
 For i = 1 To SoSV 
 Debug.Print DanhSach(i) 
 Next 
End Sub 
c. Ghi chú: Có thể áp dụng giải thuật Quic_Sort và Heap_Sort ở các bài tập trước để 
thực hiện sắp xếp trên danh sách ở dạng xâu ký tự. 
Bài tập 28: 
a. Hướng dẫn: Sử dụng các hàm thao tác xâu ký tự. 
• Hàm Trim(S) trả về xâu S nhưng không có dấu trắng ở 2 đầu (Lưu ý: Bản thân 
xâu S không bị thay đổi). 
• Hàm Replace(S, Sc, Sm) : Hàm thay thế tất cả các xâu con Sc nằm trong xâu 
cha S bằng xâu Sm. 
b. Chương trình mẫu: 
'----------------------------------------------------------------------------------------------------------------------------- 
'/// Hµm chuÈn ho¸ x©u ký tù S. Gi¸ trÞ tr¶ vÒ cho hµm lµ x©u ®−îc chuÈn ho¸ 
'/// X©u vµo ®−îc truyÒn ë d¹ng tham trÞ. Hµm kh«ng lµm thay ®æi x©u vµo S 
'----------------------------------------------------------------------------------------------------------------------------- 
Function ChuanHoa(ByVal S As String) As String 
 '/// Thªm dÊu tr¾ng vµo sau dÊu chÊm "." -> hay dấu “.” = “.” + dấu trắng 
 S = Replace(S, ".", "." & Chr(32)) 
 '//Thªm dÊu tr¾ng vµo sau dÊu ph¶y "," -> hay thay dấu “,” bằng dấu “,” + dấu trắng 
 S = Replace(S, ",", "," & Chr(32)) 
 '/// Thay 2 dÊu tr¾ng b»ng 1 dÊu tr¾ng cho ®Õn khi nµo kh«ng cßn 2 dÊu tr¾ng liÒn nhau 
 Do While InStr(1, S, Chr(32) & Chr(32)) > 0 
 S = Rep