Giáo trình Bài tập lập trình hướng sự kiện

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

pdf37 trang | Chia sẻ: maiphuongdc | Lượt xem: 2655 | Lượt tải: 1download
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

Các file đính kèm theo tài liệu này:

  • pdfpages_from_bai_tap_lap_trinh_vb_dhspkthy_1.pdf
  • pdfpages_from_bai_tap_lap_trinh_vb_dhspkthy_2.pdf
  • pdfpages_from_bai_tap_lap_trinh_vb_dhspkthy_3.pdf
  • pdfpages_from_bai_tap_lap_trinh_vb_dhspkthy_4.pdf