Khóa luận Chương trình học Tiếng Nga

Lời mở đầu Nhằm tạo điều kiện thuận lợi và linh hoạt hơn cho các bạn học sinh, sinh viên cũng như các bạn mới học tiếng Nga trong việc tra cứu từ vựng, tài liệu ngữ pháp, bài tập ứng dụng cũng như luyện kỹ năng nghe. CHương trình học tiếng Nga hướng tới đáp ứng đủ các yếu tố trên MỤC LỤC PHẦN I: GIỚI THIỆU ĐỀ TÀI VÀ CÔNG CỤ LẬP TRÌNH 7 I.1. GIỚI THIỆU ĐỀ TÀI 7 1. Mục tiêu của đề tài 7 2. Yêu cầu của đề tài 7 I.2. CÔNG CỤ LẬP TRÌNH 8 1. Các tính năng của môi trường phát triển ứng dụng delphi 8 2. Cấu trúc chương trình delphi và unit 10 3. Lệnh điều khiển trong object pascal 11 4. Các kiểu dữ liệu trong ngôn ngữ object pascal 12 5. Hàm và thủ tục 14 6. Form và các thành phần điều khiển 16 7. Lập trình đồ họa, in ấn, multimedia và các đối tượng có liên quan 18 8. Thư viện liên kết động (dll) 19 9. Giới thiệu về WIN32 API và hệ thống thông điệp 20 Phần II: TỔNG QUAN VỀ CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬ T 21 II.1. GIỚI THIỆU 21 1. Giải thuật và cấu trúc dữ liệu 21 2. Cấu trúc dữ liệu và các vấn đề liên quan 21 3. Các tiêu chuẩn đánh giá cấu trúc dữ liệu 21 4. Đánh giá độ phức tạp giải thuật 22 II.2. SẮP XẾP VÀ TÌM KIẾM 22 1.Một số giải thuật sắp xếp. 23 2. Các giải thuật tìm kiếm nội 24 II.3. CẤU TRÚC CÂY 25 1. Định nghĩa và khái niệm 25 2. Các cách biểu diễn cây 26 3. Cây nhị phân 26 4. Biểu diễn cây tổng quát bằng cây nhị phân 27 5. Cây nhị phân tìm kiếm 28 6. Cây nhị phân cân đối 29 7. Cây nhị phân tìm kiếm tối ưu 30 Phần III: TỔ CHỨC LƯU TRỮ CÂY TỪ ĐIỂN 31 Phần IV: THIẾT KẾ CHƯƠNG TRÌNH 34 V.1. TẠO BỘ GÕ VÀ FONT TIẾNG NGA CÓ DẤU NHẤN TRỌNG ÂM CHO NGƯỜI DÙNG 34 1. Khái quát về bộ gõ 34 2. Cách thiết kế bộ gõ Tiếng Nga và Tiếng Việt cho riêng chương trình 34 3. Phương pháp tạo Font Tiếng Nga mới 35 V.2. PHƯƠNG PHÁP LƯU ÂM THANH VÀ HÌNH ẢNH CHO CHƯƠNG TRÌNH TỪ ĐIỂN 37 1. Lưu âm thanh 37 2. Lưu hình ảnh 37 3. Cách thức nối kết các file âm thanh và hình vào chương trình 37 V.3. MỘT SỐ GIẢI THUẬT TRONG CHƯƠNG TRÌNH 38 1. Giải thuật tìm kiếm trên cây từ điển 38 2. Các bước tra từ 40 3. Các bước thêm từ 41 4. Các bước sửa từ 42 5. Các bước xóa từ 44 6. Giải thuật tìm kiếm nhị phân để chèn từ vào đúng vị trí trong danh sách 44 7. Mã lệnh tạo bộ gõ Tiếng Việt 46 8. Mã lệnh tạo bộ gõ Tiếng Nga 49 V.4. GIAO DIỆN CỦA CHƯƠNG TRÌNH VÀ CÁCH THỨC HOẠT ĐỘNG 51 1. Giao diện chính của chương trình với các menu thành phần 51 2. Giao diện Từ điển 52 3. Giao diện Ngữ pháp 56 4. Giao diện Bài tập 57 5. Giao diện Luyện nghe 59 6. Trang giới thiệu đề tài 62 Phần V: NHỮNG KHÓ KHĂN, THUẬN LỢI VÀ HƯỚNG PHÁT TRIỂN CHƯƠNG TRÌNH 63 1. Những khó khăn 63 2. Thuận lợi 63 3. Hướng khắc phục và phát triển chương trình 64 Phần VII: KẾT LUẬN 65 Chương trình học Tiếng Nga

doc57 trang | Chia sẻ: maiphuongtl | Lượt xem: 1773 | Lượt tải: 0download
Bạn đang xem trước 20 trang tài liệu Khóa luận Chương trình học Tiếng Nga, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
huột đến vạch phân cách, ta có thể co giãn kích thước hai biên của đối tượng canh lề. TSpliter nằm trên bảng công cụ Additional. 8. Thư viện liên kết động (dll) 8.1. Thư viện DLL Thư viện liên kết động là các đơn thể chương trình chứa mã lệnh, dữ liệu hoặc tài nguyên được dùng để chia sẻ giữa các ứng dụng Windows với nhau. DLL cho phép ứng dụng nạp và điều khiển mã lệnh vào lúc chương trình thực thi thay vì phải liên kết mã lệnh vào lúc biên dịch chương trình. DLL chia sẻ mã lệnh, tài nguyên và dữ liệu giữa nhiều tiến trình. Do vậy, các chương trình ứng dụng khác nhau có thể đồng thời gọi đến hàm hay truy xuất tài nguyên do một DLL cung cấp. 8.2. So sánh giữa liên kết tĩnh và liên kết động Liên kết động Liên kết tĩnh - Mã lệnh thực thi của hàm (thủ tục) nằm trong tập tin .dll. - Có thể được gọi từ bên ngoài và các ứng dụng khác. - Chiếm ít bộ nhớ. - Mỗi khi cập nhật hoặc nâng cấp ứng dụng thì chỉ cần thay thế bằng DLL mới mà không cần phải biên dịch lại toàn bộ chương trình .EXE. - Mã lệnh thực thi của hàm (thủ tục) nằm trong tập tin .exe. - Không gọi được từ bên ngoài và từ các ứng dụng khác. - Chiếm nhiều bộ nhớ. - Mỗi khi cập nhật hoặc nâng cấp ứng dụng thì phải biên dịch lại toàn bộ chương trình .EXE. 8.3. Sử dụng thư viện DLL Thư viện DLL được sử dụng để: * Nạp và xử lý các hàm (thủ tục) chứa trong DLL. Thư viện DLL không thể gọi thực thi trực tiếp từ dòng lệnh như các tập tin .exe mà phải được gọi gián tiếp từ các chương trình hay DLL khác. Sau khi khai báo chính xác đường dẫn thì các hàm và thủ tục chứa trong DLL được gọi và sử dụng bình thường như các hàm và thủ tục trong Unit của Delphi. * Hiển thị Form chứa trong DLL. Nếu chương trình ứng dụng cần nhiều cửa sổ Form để xây dựng giao diện phức tạp, thì việc đặt tất cả Form trong chương trình chính sẽ làm cho tập tin .exe phình to về kích thước. Vì vậy, có thể đặt Form vào bên trong DLL và gọi hiển thị Form từ chương trình chính. Có hai cách để hiển thị Form chứa trong DLL: + Hiển thị Form ở dạng modeless: khi Form phụ ở dạng modeless, người sử dụng có thể quay lại tương tác với Form chính trong khi Form phụ đang hiển thị. + Hiển thị Form ở dạng dạng model: người sử dụng không thể quay về tương tác với cửa sổ Form chính nếu cửa sổ Form phụ chưa được đóng lại. 9. Giới thiệu về WIN32 API và hệ thống thông điệp * API (Application Programming Interface), còn gọi là Giao tiếp lập trình ứng dụng, là tập hợp các lời gọi hàm cấp cao do hệ điều hành Windows cung cấp. Sử dụng Win32 API trong Delphi cần khai báo hai Unit Windows và Messages trong mệnh đề USES ở đầu chương tình như sau: Uses Windows, Messages; Trong đó thư viện Windows chứa các khai báo hàm Windows API, thư viện Messages chứa các khai báo hằng và kiểu dữ liệu. * Thông điệp Thông điệp là một mẫu tin báo hiệu do Windows phát sinh và gửi đến cửa sổ ứng dụng và hàm WndProc chính là nơi tiếp nhận và xử lý các thông điệp đó. Mỗi thông điệp chuẩn của Windows là một hằng số bắt đầu bằng tiếp đầu ngữ WM_. Mỗi thông điệp đều có ý nghĩa và cách thức xử lý khác nhau. Ví dụ: WM_KEYDOWN: Nút bàn phím bị nhấn xuống. WM_KEYUP: Nút bàn phím được nhả ra. Phần II: TỔNG QUAN VỀ CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬ T II.1. GIỚI THIỆU 1. Giải thuật và cấu trúc dữ liệu Giải thuật là một dãy các câu lệnh chặt chẽ và rõ ràng xác định một trình tự các thao tác trên một số đối tượng nào đó sao cho sau một số hữu hạn bước thực hiện ta đạt được kết quả mong muốn. Việc giải thuật đó được tác động lên dữ liệu nào và dữ liệu ấy cần được tác động giải thuật gì để đưa tới kết quả tốt. Như vậy giữa cấu trúc dữ liệu và giải thuật có mối quan hệ mật thiết. Chính điều đó đã dẫn tới việc cần nghiên cứu các cấu trúc dữ liệu đi đôi với việc xác lập các giải thuật xử lý trên các cấu trúc ấy. 2. Cấu trúc dữ liệu và các vấn đề liên quan Trong một bài toán, dữ liệu bao gồm một tập các phần tử cơ sở gọi là dữ liệu nguyên tử. Lựa chọn một cấu trúc dữ liệu thích hợp để tổ chức dữ liệu vào và trên cơ sở đó xây dựng được giải thuật xử lý hữu hiệu đưa tới kết quả mong muốn cho bài toán, đó là khâu rất quan trọng. Cách biểu diễn một cấu trúc dữ liệu trong bộ nhớ được gọi là cấu trúc lưu trữ. Đó chính là cách cài đặt cấu trúc ấy trên máy tính và trên cơ sở các cấu trúc lưu trữ này mà thực hiện các phép xử lý. 3. Các tiêu chuẩn đánh giá cấu trúc dữ liệu Một cấu trúc dữ liệu tốt phải thỏa mãn các tiêu chuẩn sau: - Phản ánh đúng thực tế: Đây là tiêu chuẩn quan trọng nhất, quyết định tính đúng đắn của toàn bộ bài toán. - Phù hợp với các thao tác trên đó: tiêu chuẩn này giúp tăng tính hiệu quả của đề án: việc phát triển các thuật toán đơn giản, tự nhiên hơn; chương trình đạt hiệu quả cao hơn về tốc độ xử lý. - Tiết kiệm tài nguyên hệ thống: thông thường có 2 loại tài nguyên cần lưu tâm nhất: CPU và bộ nhớ. 4. Đánh giá độ phức tạp giải thuật Cần tìm những phương pháp đánh giá thuật toán ít phụ thuộc môi trường cũng như phần cứng hơn. Một phương pháp như vậy là phương pháp đánh giá thuật toán theo hướng xấp xỉ tiệm cận qua các khái niệm toán học O(), o(),... Hầu hết các thuật toán đều có một tham số chính là N, thông thường đó là số lượng các phần tử dữ liệu được xử lý mà ảnh hưởng rất nhiều tới thời gian chạy. Hầu hết tất cả các thuật toán trong giáo trình này có thời gian chạy tiệm cận tới một trong các hàm sau: hằng số, logN, N, NlogN, N2, N3, 2N II.2. SẮP XẾP VÀ TÌM KIẾM Trong hầu hết các hệ lưu trữ, quản lý dữ liệu, thao tác tìm kiếm thường được thực hiện nhiều nhất để khai thác thông tin. Ví dụ: tra cứu từ điển, tìm sách trong thư viện... Do các hệ thống thông tin thường phải lưu trữ một khối lượng dữ liệu đáng kể, nên việc xây dựng các giải thuật cho phép tìm kiếm nhanh sẽ có ý nghĩa rất lớn. Nếu dữ liệu trong hệ thống đã được tổ chức theo một trật tự nào đó, thì việc tìm kiếm sẽ tiến hành nhanh chóng và hiệu quả hơn. Ví dụ: các từ trong từ điển được sắp xếp theo từng vần, trong mỗi vần lại được sắp xếp theo thứ tự bảng chữ cái; sách trong thư viện được xếp theo chủ đề, tên tác giả.... Hiện nay đã có nhiều giải thuật tìm kiếm và sắp xếp được xây dựng, mức độ hiệu quả của từng giải thuật còn phụ thuộc vào tính chất của cấu trúc dữ liệu cụ thể mà nó tác động đến. Dữ liệu được lưu trữ chủ yếu trong bộ nhớ chính và trên bộ nhớ phụ do đặc điểm khác nhau của thiết bị lưu trữ, các thuật toán sắp xếp và tìm kiếm được xây dựng cho các cấu trúc lưu trữ trên bộ nhớ chính hoặc phụ cũng có những đặc thù khác nhau. Các thuật toán sắp xếp được phân thành hai nhóm chính là: - Sắp thứ tự nội: toàn bộ dữ liệu cần sắp thứ tự phải được đưa vào trong bộ nhớ chính, nên thời gian để sắp thứ tự tương đối nhanh. - Sắp thứ tự ngoại: một phần các dữ liệu cần sắp thứ tự được đưa vào trong bộ nhớ chính, phần dữ liệu còn lại được lưu trữ ở trên bộ nhớ ngoài. Thời gian để sắp thứ tự tương đối chậm. 1.Một số giải thuật sắp xếp. Sắp xếp là quá trình xử lý một danh sách các phần tử (hoặc các mẫu tin) để đặt chúng theo một thứ tự thỏa mãn một tiêu chuẩn nào đó dựa trên nội dung thông tin lưu giữ tại mỗi phần tử. Một số phương pháp sắp xếp thông dụng như: + Sắp xếp kiểu lựa chọn (Selection Sort) + Sắp xếp kiểu thêm dần (Insertion Sort) + Sắp xếp kiểu đổi chỗ (Exchange Sort) + Sắp xếp kiểu nổi bọt (Bubble Sort) + Sắp xếp kiểu phân đoạn (Quick Sort) + Sắp xếp kiểu vun đống (Heap Sort) + Sắp xếp kiển hòa nhập (Merge Sort) + Sắp xếp với độ dài bước giảm dần (Shell Sort) + Sắp xếp theo phương pháp cơ số (Radix Sort) Nhận xét và đánh giá các thuật toán sắp xếp: Phần lớn các thuật toán sắp xếp cơ bản dựa trên sự so sánh giá trị giữa các phần tử. Đó là các thuật toán chọn lựa, thêm dần, nổi bọt, đổi chỗ. Các thuật toán này đều có một điểm chung là chi phí thực hiện chung là tỉ lệ với n2. Các thuật toán shell-sort (cải tiến của phương pháp thêm dần), heap-sort (cải tiến của phương pháp chọn lựa) lại có độ phức tạp nhỏ hơn hẳn các thuật toán gốc. Thuật toán shell-sort có độ phức tạp O(nx) với 1 < x < 2 và thuật toán heap-sort có độ phức tạp O(nlog2n). Các thuật toán merge-sort và quick-sort là những thuật toán thực hiện theo chiến lược chia để trị. Cài đặt chúng tuy phức tạp hơn các thuật toán khác nhưng chi phí thực hiện lại thấp, cả hai thuật toán đều có độ phức tạp O(nlog2n). Merge-sort có nhược điểm là cần dùng thêm bộ nhớ đệm. Thuật toán này sẽ phát huy tốt ưu điểm khi cài đặt trên các cấu trúc dữ liệu khác phù hợp hơn như danh sách liên kết hay phi. Thuật toán quick-sort được đánh giá là thuật toán sắp xếp nhanh nhất trong số các thuật toán sắp xếp dựa trên nền tảng so sánh giá trị của các phần tử. Tuy có chi phí trong trường hợp xấu nhất là O(n) nhưng trong kiểm nghiệm thực tế, thuật toán quick-sort chạy nhanh hơn hai thuật toán cùng nhóm O(nlog2n) là merge-sort và heap-sort. Thuật toán Radix-sort là một thuật toán được phát triển theo hướng khác với các thuật toán trên. Nó được phát triển dựa trên mô phỏng qui trình phân phối thư của người đưa thư. Thuật toán này đại diện cho nhóm các thuật toán sắp xếp có độ phức tạp tuyến tính. Tuy nhiên, thường thì các thuật toán này không thích hợp cho việc cài đặt trên cấu trúc dữ liệu mảng một chiều. 2. Các giải thuật tìm kiếm nội Thông thường các dữ liệu được phân chia thành các bản ghi, mỗi bản ghi có một khoá được sử dụng trong việc tìm kiếm. Vấn đề của việc tìm kiếm là tìm tất cả các mẩu tin có cùng khoá k cho biết trước để truy xuất nội dung của bản ghi. Công việc tìm kiếm sẽ hoàn thành khi có một trong hai tình huống sau xảy ra: - Tìm được bản ghi có giá trị khóa tương ứng, lúc đó ta nói: phép tìm kiếm được thỏa. - Không tìm được bản ghi nào có giá trị khóa tương ứng: phép tìm kiếm không thỏa. Sau khi phép tìm kiếm không thỏa có khi xuất hiện yêu cầu bổ sung thêm bản ghi mới có khóa không tìm thấy vào bảng. Giải thuật thể hiện cả yêu cầu này được gọi là giải thuật “Tìm kiếm có bổ sung”. Ta có một số thuật toán tìm kiếm như: + Tìm kiếm tuần tự + Tìm kiếm nhị phân + Tìm kiếm dựa vào giá trị khóa Nhận xét và đánh giá các thuật toán tìm kiếm: Giải thuật tìm nhị phân dựa vào quan hệ giá trị của các phần tử mảng để định hướng trong quá trình tìm kiếm, do vậy chỉ áp dụng được cho những dãy đã có thứ tự. Giải thuật tìm nhị phân tiết kiệm thời gian hơn rất nhiều so với giải thuật tìm kiếm tuần tự do Tnhị phân(n) = O(log2n) < Ttuần tự(n) = O(n). Tuy nhiên khi muốn áp dụng giải thuật tìm nhị phân cần phải xét đến thời gian sắp xếp dãy số để thỏa điều kiện dãy số có thứ tự. Với phương pháp tìm kiếm dựa vào giá trị khóa, các khóa có giá trị khác nhau cũng có thể cùng ứng với một địa chỉ và hiện tượng này được gọi là hiện tượng đụng độ. Vì vậy khi xét phương pháp này, không những cần chú ý đến cách xây dựng hàm địa chỉ mà còn phải xét cả tới phương pháp khắc phục đụng độ. II.3. CẤU TRÚC CÂY 1. Định nghĩa và khái niệm * Định nghĩa cây Cây là một tập hợp T rỗng hoặc gồm nhiều phần tử được gọi là nút, trong đó: - Một nút được gọi là nút gốc (root). - Các nút còn lại được phân chia thành m nhóm (m>=0), mỗi nhóm là một cây và được gọi là cây con. Trong đó nút có thể được xem như là một phần tử của một danh sách và có thể có kiểu bất kỳ. Các nút được biểu diễn bởi một ký tự chữ, một chuỗi, một số ghi trong một vòng tròn. Giữa các nút có một quan hệ phân cấp gọi là “quan hệ cha con”, các nút ngay bên trên trực tiếp là nút cha, các nút ngay bên dưới trực tiếp là các con của nút đó. Một cây không có một nút nào cả gọi là cây rỗng. * Một số khái niệm cơ bản - Bậc của một nút: là số cây con của nút đó - Bậc của một cây: là bậc lớn nhất của các nút trong cây (số cây con tối đa của một nút thuộc cây). Cây có bậc n thì gọi là cây n-phân. - Nút gốc: là nút không có nút cha. - Nút lá: là nút có bậc bằng 0. - Nút nhánh: là nút có bậc khác 0 và không phải là gốc - Rừng cây: là tập hợp nhiều cây trong đó thứ tự các cây là quan trọng. 2. Các cách biểu diễn cây Để biểu diễn một cây, ta có nhiều cách: a) Biểu diễn cây bằng đồ thị b) Biểu diễn cây bằng giản đồ c) Biểu diễn cây bằng các dấu ngoặc lồng nhau d) Biểu diễn cây bằng phương pháp Indentation e) Biểu diễn cây bằng chỉ số 3. Cây nhị phân * Khái niệm: Cây nhị phân là một dạng quan trọng của cấu trúc cây. Nó có đặc điểm là: mọi nút trên cây chỉ có tối đa là hai cây con (cây con trái và cây con phải). Cây nhị phân là cây có thứ tự. 3.1. Biểu diễn cây nhị phân - Lưu trữ kế tiếp: cây được lưu trữ bằng một vectơ V với nút thứ i của cây được lưu trữ ở V[i]. Với cách lưu trữ này nếu biết được địa chỉ nút cha sẽ tính được địa chỉ nút con và ngược lại. Tuy nhiên nếu cây nhị phân không đầy đủ thì cách lưu trữ này không thích hợp vì sẽ gây ra lãng phí do có nhiều phần tử nhớ bỏ trống (ứng với cây con rỗng). A B C F D E G Ví dụ: Với cây nhị phân Biểu diễn phương pháp lưu trữ kế tiếp của cây nhị phân trên như sau: A B C D E È G V[1] V[2] V[3] V[4] V[5] V[6] V[7] - Lưu trữ móc nối: mỗi nút của cây ứng với một phần tử nhớ gồm ba trường là: trường INFO ứng với thông tin dữ liệu của nút; trường LPTR ứng với con trỏ trỏ tới cây con trái của nút đó; trường RPTR ứng với con trỏ trỏ tới cây con phải của nút đó. Với cách biểu diễn này thì nút cha có thể truy nhập vào nút con dễ dàng, nhưng ngược lại thì không làm được Ví dụ: Với cây nhị phân trên ta có phương pháp lưu trữ móc nối như sau A B C D G E F 3.2. Duyệt cây nhị phân Có ba phép duyệt khác nhau đối với cây nhị phân. - Duyệt theo thứ tự trước: Kiểu duyệt này trước tiên thăm gốc sau đó thăm các nút của cây con trái rồi đến cây con phải. - Duyệt theo thứ tự giữa: Kiểu duyệt này trước tiên thăm các nút của cây con trái sau đó thăm nút gốc rồi đến cây con phải. - Duyệt theo thứ tự sau: Kiểu duyệt này trước tiên thăm các nút của cây con trái sau đó thăm đến cây con phải rồi cuối cùng mới thăm nút gốc. 4. Biểu diễn cây tổng quát bằng cây nhị phân - Cây tổng quát: có đặc điểm là mọi nút trên cây có thể có nhiều hơn hai cây con. - Nhược điểm của các cấu trúc cây tổng quát là bậc của các nút trên cây có thể dao động trong một biên độ lớn, nên việc biểu diễn gặp nhiều khó khăn và lãng phí. Hơn nữa, việc xây dựng các thao tác trên cây tổng quát phức tạp hơn trên cây nhị phân nhiều. Vì vậy, thường nếu không quá cần thiết phải sử dụng cây tổng quát, người ta chuyển cây tổng quát thành cây nhị phân. Ta có thể biến đổi một cây bất kỳ thành một cây nhị phân theo qui tắc sau: + Giữ lại nút con trái nhất làm nút con trái. + Các nút con còn lại chuyển thành nút con phải. + Như vậy, trong cây nhị phân mới, con trái thể hiện quan hệ cha con và con phải thể hiện quan hệ anh em trong cây tổng quát ban đầu. Khi đó cây tổng quát biểu diễn theo qui tắc trên được gọi là cây nhị phân tương đương. B A C E F G D H I J A B E C D G H I J F Ví dụ: Cây tổng quát chuyển sang cây nhị phân 5. Cây nhị phân tìm kiếm * Định nghĩa: Cây nhị phân tìm kiếm (CNPTK) là cây nhị phân trong đó tại mỗi nút, khóa của nút đang xét lớn hơn khóa của tất cả các nút thuộc cây con trái và nhỏ hơn khóa của tất cả các nút thuộc cây con phải. Nhờ ràng buộc về khóa trên CNPTK, việc tìm kiếm trở nên có định hướng. Hơn nữa, do cấu trúc cây việc tìm kiếm trở nên nhanh đáng kể. Nếu số nút trên cây là N thì chi phí tìm kiếm trung bình chỉ khoảng log2N. * Các thao tác trên cây nhị phân tìm kiếm: a) Duyệt cây: Thao tác duyệt cây trên cây nhị phân tìm kiếm hoàn toàn giống như trên cây nhị phân. Chỉ có một lưu ý nhỏ là khi duyệt theo thứ tự giữa, trình tự các nút duyệt qua sẽ cho ta một dãy các nút theo thứ tự tăng dần của khóa. b) Thêm một phần tử x vào cây: Việc thêm vào phải bảo đảm điều kiện ràng buộc của CNPTK. Ta có thể thêm vòa nhiều chỗ khác nhau trên cây, nhưng nếu thêm vào một nút lá sẽ là tiện lợi nhất do ta có thể thực hiện quá trình tương tự thao tác tìm kiếm. Khi chấm dứt quá trình tìm kiếm cũng chính là lúc tìm được chỗ cần thêm. c) Hủy một phần tử có khóa x: Việc hủy một phần tử x ra khỏi cây phải bảo đảm điều kiện ràng buộc của CNPTK. Có 3 trường hợp khi hủy nút x có thể xảy ra: + x là nút lá: chỉ đơn giản hủy x vì nó không móc nối đến phần tử nào khác. + x chỉ có 1 con (trái hoặc phải): trước khi hủy x ta móc nối cha của x với con duy nhất của nó. + x có đủ cả 2 con: ta không thể hủy trực tiếp do x có đủ 2 con. Vì vậy ta sẽ hủy gián tiếp. Thay vì hủy x, ta sẽ tìm một phần tử thế mạng y. Phần tử này có tối đa một con. Thông tin lưu tại y sẽ được chuyển lên lưu tại x. Sau đó, nút bị hủy thật sự sẽ là y giống như 2 trường hợp đầu. Vấn đề là phải chọn y sao cho khi lưu y vào vị trí của x, cây vẫn là CNPTK. Có 2 phần tử thỏa mãn yêu cầu: Phần tử nhỏ nhất (trái nhất) trên cây con phải và phần tử lớn nhất (phải nhất) trên cây con trái. d) Tạo một cây CNPTK: Ta có thể tạo một cây nhị phân tìm kiếm bằng cách lặp lại quá trình thêm 1 phần tử vào một cây rỗng. e) Hủy toàn bộ CNPTK: Việc toàn bộ cây có thể được thực hiện thông qua thao tác duyệt cây theo thứ tự sau. Nghĩa là ta sẽ hủy cây con trái, cây con phải rồi mới hủy nút gốc. 6. Cây nhị phân cân đối * Cây nhị phân cân đối hoàn toàn: là cây nhị phân tìm kiếm mà tại mỗi nút của nó, số nút của cây con trái chênh lệch không quá một so với số nút của cây con phải. Nhận xét: Một cây khó đạt được trạng thái cân bằng hoàn toàn. Tuy nhiên nếu cây cân đối thì việc tìm kiếm sẽ nhanh, trong trường hợp xấu nhất ta chỉ phải tìm qua log2n phần tử (với n là số nút trên cây). Do cây cân đối hoàn toàn là một cấu trúc kém ổn định nên trong thực tế không thể sử dụng. * Cây nhị phân cân đối: là cây mà tại mỗi nút của nó độ cao của cây con trái và của cây con phải chênh lệch không quá một. Nhận xét: Cây cân đối hoàn toàn là cây cân bằng. Điều ngược lại không đúng. Tuy nhiên cây cân đối là cấu trúc dữ liệu ổn định hơn hẳn cây cân đối hoàn toàn. Từ cây cân đối người ta đã phát triển thêm nhiều lại cấu trúc dữ liệu hữu dụng khác như cây đỏ-đen, B-cây,... 7. Cây nhị phân tìm kiếm tối ưu Xây dựng cây nhị phân tìm kiếm tương ứng với các từ khóa. Đối với các từ khóa có xác suất xuất hiện lớn thì cần phải được tìm thấy nhanh hơn, nghĩa là tương ứng với đường đi ngắn hơn. Muốn thế gắn với mỗi khóa (nút) một trọng số, đó chính là xác suất xuất hiện của khóa này trong tìm kiếm. Và mục đích là xác định được cây nhị phân tìm kiếm sao cho tổng độ dài đường đi có trọng số tương ứng với mọi nút trên cây (hay còn gọi là độ dài đường đi có trọng số của cây) có giá trị nhỏ nhất. Tuy nhiên việc chọn một cây có trọng số nhỏ nhất là một công vệc khó thực hiện khi n khá lớn. Vậy để giải quyết vấn đề này ta thực hiện theo nguyên tắc sau: “Đối với một cây nhị phân tìm kiếm tối ưu thì bất kỳ một cây con nào của nó cũng phải là cây nhị phân tìm kiếm tối ưu ”. Từ đó dẫn tới một giải thuật cho phép dựng được cây nhị phân tìm kiếm tối ưu lớn dần lên bắt đầu từ một nút lá mà ta gọi là kỹ thuật dựng cây nhị phân tìm kiếm tối ưu theo kiểu “từ đáy lên” (bottom up). Phần III: TỔ CHỨC LƯU TRỮ CÂY TỪ ĐIỂN Một cấu trúc dữ liệu khá điển hình và hợp lý với bài toán từ điển là: cấu trúc cây từ điển. Quản lý từ điển có dạng cây là kỹ thuật thường được sử dụng để xử lý những từ điển lớn nhằm thu nhỏ dung lượng. Cây từ điển là tập hợp các bản ghi liên kết với nhau (còn gọi là phương pháp lưu trữ móc nối). Mỗi bản ghi gọi là một nút trong cây. Để quản lý cây từ điển ta luôn luôn phải giữ địa chỉ của cây, tức là nút gốc (nút đầu tiên của cây). Mỗi nút cây từ điển gồm có 3 trường: + Trường Info: chứa một kí tự kiểu CHAR. + Trường Left: chỉ đến nút Anh Em của nó. + Trường Right: chỉ đến nút con của nó. Một nút B gọi là con của nút A nếu B = A.left Tương tự nút B gọi là nút Anh Em của nút A nếu: B = A.right (hoặc A = B.right). Từ đây mở rộng ra: nếu B là Con của A và C là Anh Em của B thì cả B và C đều là Con của A. Nếu A là Anh Em của B và B là Anh Em của C thì A cũng là Anh Em của C. Để tạo thành cây từ điển trong quá trình chạy chương trình, ta phải làm thao tác nạp các từ tiếng Nga vào cây. Về trường nghĩa của từ, vì nó rất lớn nên không thể nạp vào bộ nhớ chương trình được. Vì vậy ta phải để nghĩa của từ ở trong File. Điều này bắt buộc ta phải xen kèm vào trong cây từ điển (tương ứng sau mỗi từ tiếng Nga) chỉ số vị trí của từ tiếng Nga đó trong File. Và tất nhiên chỉ số này phải được đổi thành chuỗi kí tự thập phân trước khi thực hiện xen từ. Khi đọc thì sẽ chuyển ngược chuỗi chỉ số này sang số thập phân. Ví dụ: Với các từ tiếng Nga: /ỉĩð/çư/ç/çð//ÿ/ ỉí. Khi lưu trữ trên cây, các từ tiếng Nga này sẽ là các chuỗi có cấu trúc như sau: *1 ỉĩð*2 çư*3 ç*4 çð*5 *6 ÿ*7 ỉí*8 ta có cấu trúc cây từ điển như sau: * * 1 ỉ ĩ ð 2 ç ư * * 3 ç * 4 ð * 5 * 6 * ÿ 7 ỉ í * 8 Root Nút đánh dấu kết thúc của mỗi từ Nút đánh dấu số thứ tự bản ghi của mỗi từ, sử dụng cho việc tìm kiếm và tra từ Nút thể hiện từng ký tự của mỗi từ Nhận xét: Theo cây từ điển được minh hoạ ở trên, kí tự ‘*’ được sử dụng làm ký tự đánh dấu ở đầu cấu trúc cây và làm ký tự kết thúc của một từ. Như vậy theo cây từ điển thì mỗi từ tiếng Nga ngoài các kí tự hình thành còn có thêm kí tự ‘*’ ở cuối mỗi từ để đánh dấu và các kí tự chữ số để đánh số thứ tự từng bản ghi trong file dữ liệu hỗ trợ cho quá trình tìm kiếm trên cây. Mỗi từ trong từ điển tương ứng với một bản ghi gồm ba trường: wordRec = record wordRus: string[25]; // trường Tiếng Nga wordMea: string[200]; // trường nghĩa Tiếng Việt STT:string[6];// trường số thứ tự cho hình ảnh, âm thanh end; Như vậy để chứa các từ trên cây chỉ mất rất ít số bản ghi so với dữ liệu của nó. Với cấu trúc này ta có thể nạp vào chương trình khi chạy tất cả các từ có trong một bộ từ điển lớn khoảng 100.000 từ mà không sợ bị tràn bộ nhớ. Hơn nữa thuật toán xây dựng các thao tác trên cây từ điển này sẽ hoạt động rất nhanh mà không phụ thuộc vào kích thước dữ liệu đầu vào. Khi chương trình hoạt động, mỗi lần ta đánh vào một kí tự (trong quá trình nhập từ để tra) chương trình sẽ phải duyệt cây từ điển để tìm ra các từ gần giống với chuỗi từ mà ta đang nhập nhất. Danh sách các từ này sẽ hiện ra giao diện chương trình. Quá trình duyệt bắt đầu từ nút gốc (Root) dần dần xuống tới các nút con. Đặc điểm của cây từ điển có rất nhiều nút lá, chiều cao của cây lại rất thấp (do số kí tự tạo ra từ không nhiều). Điều này rất thích hợp cho ta trong việc thường xuyên phải tìm kiếm trên cây. Thuật toán xây dựng trên cấu trúc dữ liệu này sẽ đơn giản và hoạt động rất nhanh. Kết luận: Đối với dạng cây Từ Điển đã nói ở trên ta thấy cây Từ Điển là một cây dạng tổng quát có tiền tố chung. Nhưng để ở dạng cây tổng quát thì việc thực hiện các thao tác và các phép xử lý trên cây khó khăn, cho nên cây được chuyển về dạng cây nhị phân với thuật toán chuyển đã trình bày. Qua dạng cấu trúc của cây nhị phân Từ Điển ta có nhận xét chung: Một từ luôn được kết thúc trên nhánh cây con trái. Các từ có tiền tố chung khi chúng là cây con phải của nút con trái của nút chứa kí tự cuối cùng thuộc chuỗi tiền tố. Từ nhận xét trên chúng ta có thể xây dựng được các giải thuật tìm kiếm, thêm, loại bỏ… một cách chính xác. Phần IV: THIẾT KẾ CHƯƠNG TRÌNH V.1. TẠO BỘ GÕ VÀ FONT TIẾNG NGA CÓ DẤU NHẤN TRỌNG ÂM CHO NGƯỜI DÙNG 1. Khái quát về bộ gõ Khi nhập từ, vấn đề xác định kí tự tiếng Nga trên bàn phím đối với người sử dụng là rất khó khăn. Vì thế, chương trình Từ điển này đã hỗ trợ một bộ gõ tiếng Nga cho người dùng trong quá trình tra từ, khi người dùng không nhớ vị trí của kí tự. Tuy thô sơ nhưng giải pháp này phần nào đã mang lại cho người dùng cảm giác thoải mái khi sử dụng bộ gõ. Với giao diện bàn phím nhìn thấy được trên màn hình, người sử dụng chưa quen với bàn phím tiếng Nga có thể xác định được các phím của kí tự tiếng Anh tương ứng với từng ký tự tiếng Nga, qua đó người sử dụng có thể gõ được các từ tiếng Nga một cách dễ dàng. Cũng với giao diện này ta có thể thiết kế để người sử dụng dùng chuột click vào các phím trên bộ gõ để được từ mong muốn. 2. Cách thiết kế bộ gõ Tiếng Nga và Tiếng Việt cho riêng chương trình Khi sử dụng chương trình Từ điển, nếu trên máy người dùng không cài đặt các chương trình như VietKey, VietWare.... thì không thể thực hiện được chức năng tra từ tiếng Nga cũng như thêm từ tiếng Việt. Vì vậy, việc tạo một bộ gõ tiếng Nga và tiến Việt riêng cho chương trình là điều cần thiết. Bằng font tiếng Nga tự thiết kế và một số font tiếng Việt có sẵn của VietKey, dựa vào bảng mã ASCII của phông chữ chúng ta có thể biết được các mã tương ứng từng chữ cái tiếng Nga cũng như tiếng Việt. Với ngôn ngữ Delphi có hỗ trợ thủ tục chặn thông điệp các phím bấm từ bàn phím (thủ tục PostMessage). Để tạo ra được các ký tự tiếng Nga, tiếng Việt tương ứng với phím gõ chương trình cần phải chặn được thông điệp đến từ bàn phím, xác định được phím gõ tương ứng với phím nào của bàn phím tiếng Nga cũng như tiếng Việt. Bình thường thì ký tự hiển thị trên màn hình sẽ là ký tự Latinh tương ứng phím gõ, do đó để hiển thị được ký tự tiếng Nga chương trình cần phải xóa ký tự Latinh và thay thế bằng ký tự tiếng Nga. Việc thay thế ký tự tiếng Nga được dựa trên mã ASCII của font chữ tiếng Nga được dùng để hiển thị. Hai thủ tục sau trong chương trình sẽ thực hiện việc xóa ký tự Latinh và thay vào ký tự tiếng Nga: 1 PostMessage (frmNgaVietAnh.cboNhapTu.handle, WM_CHAR, 8, 1); 2 PostMessage (frmNgaVietAnh.cboNhapTu.handle, WM_CHAR, MaFont, 1); 1 Dùng để xóa ký tự Latinh với mã ASCII bằng 8 là mã của phím Del. 2 Dùng để hiển thị ký tự Nga có MaFont tương ứng với mã ASCII trong phông tiếng Nga của phím được gõ. Hàm PostMessage cũng được sử dụng tương tự cho ký tự tiếng Việt. 3. Phương pháp tạo Font Tiếng Nga mới Phông chữ tiếng Nga hiện nay vẫn đang là một vấn đề quan tâm của người dùng. Trong những font chữ hỗ trợ tiếng Nga hiện nay của các phần mềm như Vietkey 2002, VietKey4.0, Unikey,...thì không một font nào có kí tự dấu trọng âm ( là một âm nhấn trên đầu mỗi từ ) nhằm giúp người dùng biết cách phát âm của từ một cách chính xác . Tạo một bộ font mới tưởng chừng là một vấn đề nan giải, nhưng hiện nay với sự hỗ trợ của nhiều phần mềm chuyên dụng thì việc giải quyết không còn mấy khó khăn. Với phần mềm Photographer 4.1, bạn có thể tạo ra một bộ font tùy ý với kí tự do chính bạn thiết kế. Các bước tạo font trên Photographer được tiến hành như sau: - Chọn một bộ font mới, sau đó ứng với từng kí tự trên bàn phím ta có thể vẽ các kí tự bằng các công cụ thiết kế đồ họa được cung cấp sẵn trong phần mềm này. - Sau đó lưu lại để tạo ra một bộ font mơi, đó chính là font RussTimes SNG được sử dụng trong chương trình này. Kí tự dấu nhấn trọng âm sau khi được thiết kế xong. Bảng công cụ thiết kế kí tự của chương trình. Vị trí của dấu nhấn trọng âm trong bộ font mới tạo. Nhờ phần mềm này mà chương trình học tiếng Nga đã có một bộ font mới với đầy đủ các chức năng cần thiết cho việc nhập dữ liệu của chương trình. V.2. PHƯƠNG PHÁP LƯU ÂM THANH VÀ HÌNH ẢNH CHO CHƯƠNG TRÌNH TỪ ĐIỂN 1. Lưu âm thanh Sau khi thu âm giọng đọc từ bên ngoài vào máy thông qua chương trình JetAudio, hoặc chương trình Recoder. Phiên âm tiếng Nga được tách và lưu thành các file .mp3. Việc tách thành các file (.MP3) sẽ tiết kiệm bộ nhớ hơn so với các file (.WAV). Ngôn ngữ Delphi cho phép mở tập tin âm thanh (.WAV) với hàm PlaySound(). Tuy nhiên hàm này lại không hỗ trợ việc mở các tập tin âm thanh (.MP3), trong khi đó hầu hết các dạng tập tin multimedia, từ âm thanh cho đến phim ảnh, như (.WAV), (,MP3), (.MINI), (.DAT), (.AVI).... đều có thể mở được thông qua đối tượng TMediaPlayer được cung cấp trong ngôn ngữ lập trình. Vì vậy, chương trình đã sử dụng tập hợp các nút nhấn điều khiển thông dụng như Play, Stop, Pause... của đối tượng TMediaPlayer để thực hiện việc mở các tập tin âm thanh. 2. Lưu hình ảnh Ảnh được nạp vào chương trình thông qua đối tượng TImage của ngôn ngữ lập trình. Để nạp ảnh từ tập tin vào đối tượng TImage, ta sử dụng thuộc tính TImage.Picture và gọi phương thức LoadFromFile. 3. Cách thức nối kết các file âm thanh và hình vào chương trình Mỗi từ trong từ điển tương ứng với một bản ghi gồm ba trường như sau: wordRec = record wordRus: string[25]; // trường Tiếng Nga wordMea: string[200]; // trường nghĩa Tiếng Việt STT:string[6];// trường số thứ tự cho hình ảnh, âm thanh end; Tên các file âm thanh và hình ảnh được gắn số thứ tự tương ứng với các trường STT của mỗi từ. Vì thế sau khi hiện nghĩa Tiếng Việt, nếu tìm thấy tên file âm thanh hay hình ảnh tương ứng với số thứ tự của trường STT thì các file này được nạp để gọi trong chương trình. V.3. MỘT SỐ GIẢI THUẬT TRONG CHƯƠNG TRÌNH Các giải thuật hầu hết được cài đặt qua các hàm, thủ tục DLL. Chúng được gọi từ các chương trình DLL khác. Việc sử dụng các hàm, thủ tục DLL giúp người lập trình tránh được những câu lệnh phức tạp, dài dòng đồng thời chương trình trở nên chặt chẽ, dễ hiểu và dễ sửa chữa khi có sai sót trong quá trình thử nghiệm. Một số giải thuật được sử dụng trong chương trình Từ điển Nga – Việt gồm: 1. Giải thuật tìm kiếm trên cây từ điển - Duyệt cây từ điển bắt đầu từ nút gốc - So sánh từng kí tự của chuỗi cần tìm kiếm có thêm kí tự ‘*’ ở cuối chuỗi với từng nút trên cây. - Nếu kết thúc quá trình duyệt cây gặp kí tự ‘*’ thì thông báo tìm kiếm thành công. Ngược lại thì thông báo quá trình tìm kiếm không thành công. //** Hàm tìm từ trên cây Từ điển Function _FindWord(var p,q: TNode; st: string): Boolean;export;stdcall; var i: integer; ketQua, Found: Boolean; begin i:= 1; p:= Root; Found:=false; ketQua:= false; st:= st + '*'; While (i <length(st)) and (not ketQua) do begin q:=p; if st[i]= #96 then inc(i); {ki tu trong am} if st[i] < p^.Info then begin ketQua:= true; Found:= False; end else if st[i] > p^.Info then if p^.Right nil then begin p:= p^.Right; ketQua:= false; end else begin ketQua:= true; Found:=false; end else if p^.Left nil then if st[i]='*' then begin ketQua:=true; Found:=true; end else begin p:= p^.Left; inc(i); ketQua:=false; end else begin ketQua:=true; Found:=false; end; end; _FindWord:= Found; end; 2. Các bước tra từ - Gọi hàm tìm từ. - Nếu tìm không thành công thì thông báo lỗi “Từ không có trong từ điển”. - Ngược lại: + Đọc tiếp các nút chữ số đánh dấu số thứ tự của các bản ghi trong file dữ liệu. + Đổi chuỗi số đọc được thành số. + Mở file dữ liệu, chuyển con trỏ file vị trí bản ghi cần tìm. + Xuất trường nghĩa của bản ghi ra màn hình. //** Thủ tục tra từ trong từ điển procedure_SearchWordNV(var keyWor: integer; st: string; MForm: TfrmNgaVietAnh); export;stdcall; var p,q:TNode; findWor:boolean; f:file of TWordNV; word:TWordNV; Begin st:= st + '*'; findWor:= _FindWord(p,q,st); If not findWor then ShowMessage('Khong tim thay tu trong tu dien') Else begin st:= ''; repeat { Doc thong tin cac nut luu so khoa-so thu tu ban ghi} begin p:= p^.Left; st:= st + p^.Info; end; until p^.Left = nil; keyWor:= StrToInt(st); AssignFile(f,FileName); Reset(f); Seek(f,keyWor); read(f,word); MForm.retTuViet.Lines.CommaText:= word.VieMean; MForm.lblHienChu.Caption:=word.RusWord; CloseFile(f); end; end; 3. Các bước thêm từ - Gọi thủ tục tìm từ. - Nếu tìm thành công thì thông báo “Từ đã có trong từ điển”. - Ngược lại: + Thêm từ vào cuối danh sách. + Thêm từ vào cuối file dữ liệu. + Thêm từ vào cây. //** Thủ tục thêm từ trong từ điển procedure _AddWord(MForm: TfrmNgaVietAnh; stWor: string; stMea: string); export; stdcall; var p,q: TNode; findWor: Boolean; st: string; f: file of TWordNV; recNum: integer; begin st:= stWor + '*'; findWor:= _FindWord(p,q,st); // Ham tim tu If findWor then ShowMessage('Tu da co trong tu dien')//_ErrorMsg(3) // Thong bao co tu trong Tu Dien Else begin AssignFile(f,FileName); Reset(f); try recNum:= FileSize(f); finally CloseFile(f); end; st:= st + IntToStr(recNum); // Gan so ban ghi vao chuoi tu de de tim MForm.lstDSNV.Items.Add(stWor); _AddToFile(stWor,stMea); _AddToTree(st); // Thu tuc "Them tu vao cay" ShowMessage('T míi ®· ®­ỵc l­u!'); end; end; 4. Các bước sửa từ - Gọi thủ tục tìm từ. - Nếu tìm không thành công thì thông báo “Không có từ trong từ điển”. - Ngược lại: + Mở file dữ liệu. + Đưa con trỏ file đến vị trí bản ghi tương ứng. + Ghi đè bản ghi mới lên bản ghi cũ. / /** Thủ tục sửa từ trong từ điển procedure _RepairWord(stOld:string; stWor: string; stMea: string);export; stdcall; var f: file of TWordNV; findWor:boolean; key:integer; p,q:TNode; worRec:TWordNV; st: string; begin key:=0; st:= stOld + '*'; findWor:= _FindWord(p,q,st); If not findWor then ShowMessage('Tu khong co trong tu dien') //_ErrorMsg(2) Else begin //Doc khoa Repeat p:= p^.Left; key:= key + StrToInt(p^.Info); until p^.Left= nil; worRec.RusWord:= stWor; worRec.VieMean:= stMea; //Mo file AssignFile(f,FileName); Reset(f); //Ghi de len ban ghi hien hanh Seek(f,key); write(f,worRec); CloseFile(f); ShowMessage('Từ sửa đã được lưu!'); end; end; 5. Các bước xóa từ - Gọi thủ tục tìm từ. - Nếu không tìm thấy từ thì thông báo “Từ không có trong từ điển”. - Ngược lại: + Xoá trường tiếng Nga trong danh sách hiển thị từ. + Xoá bản ghi chứa từ trong file. + Xoá kí tự “*” đánh dấu ở cuối từ cần xoá trên cây. //** Thủ tục xóa từ trong từ điển procedure _DelWord(MForm:TfrmNgaVietAnh; st: string);export;stdcall; var findWor:boolean; p, q: TNode; begin st:= st + '*'; findWor:= _FindWord(p,q,st); If not findWor then ShowMessage('Khong tim thay tu trong tu dien')//_ErrorMsg(2) Else begin DelWordInFile(p); DelWordInTree(q,p); DelWordInList(MForm, st); ShowMessage('Từ đã được xóa khỏi Từ Điển!'); end; end; 6. Giải thuật tìm kiếm nhị phân để chèn từ vào đúng vị trí trong danh sách - Tìm kiếm trong danh sách đã được sắp xếp thứ tự. - Tìm vị trí giữa của danh sách ( i ). - Lần lượt so sánh từng kí tự của từ cần chèn (giả sử là x) với kí tự của từ tại vị trí i của danh sách (giả sử là y) theo qui tắc sau: + Nếu x=y thì từ được tìm thấy. + Nếu x<y thì từ có trong khoảng từ đầu danh sách đến kí tự thứ i-1. + Nếu x>y thì kí tự có phạm vi phía sau y. - Sau khi xác định đúng vị trí thì từ sẽ được chèn vào danh sách. //** Thủ tục tìm kiếm và chèn từ Function FindCharFirst(st:string;len:word):word;export;stdcall; Var Tim:boolean; l,r,m:word; begin Tim:=false; l:= 0; r:= len; While (l<=r) and (Tim = false) do begin m:=(l+r)div 2; If st<frmNgaVietAnh.lstDSNV.Items[m] then r:=m-1 Else If st>frmNgaVietAnh.lstDSNV.Items[m] then l:=m+1 else Tim:= true; end; If l<= r then begin While st= frmNgaVietAnh.lstDSNV.Items[m] do m:=m-1; m:= m+1; end; FindCharFirst:= m; end; {===========} Function FindCharNext(st:string;index:word):word;export;stdcall; var m:word; begin While st< frmNgaVietAnh.lstDSNV.Items[index] do index:=index+1; If st=frmNgaVietAnh.lstDSNV.Items[index] then m:=index; If st> frmNgaVietAnh.lstDSNV.Items[index] then m:=index-1; FindCharNext:=m; end; {===========} Procedure _FindWordInDS(st:string;len:word);export;stdcall; begin If st = '' then index:= 0; If length(st)=1 then index := FindCharFirst(st,len) Else index := FindCharNext(st,index); {Di chuyen den vi tri can tim trong danh sach} SendMessage(frmNgaVietAnh.lstDSNV.Handle, lb_SetTopIndex, frmNgaVietAnh.lstDSNV.ItemIndex-1, 0); end; 7. Mã lệnh tạo bộ gõ Tiếng Việt //** Thủ tục tạo Bộ gõ Tiếng Việt dùng cho các đối tượng có FONT Việt procedure _VietFont; var prevchar, key:char; begin if msg.message=WM_CHAR then begin key:=chr(msg.wParam); case key of '1':case prevchar of 'a','e','o','u','y','i',chr(246),chr(244):key:=chr(249); 'A','E','O','U','Y','I',chr(214),chr(212):key:=chr(217); chr(234),chr(202),chr(226),chr(194):begin PostMessage(Editor.handle,WM_CHAR,8,1); PostMessage(Editor.handle,WM_CHAR,ord(prevchar)-1,1); handled:=true; end; end; '2':case prevchar of 'a','e','o','u','y','i',chr(246),chr(244):key:=chr(248); 'A','E','O','U','Y','I',chr(214),chr(212):key:=chr(216); chr(234),chr(202),chr(226),chr(194):begin PostMessage(Editor.handle,WM_CHAR,8,1); PostMessage(Editor.handle,WM_CHAR,ord(prevchar)-2,1); handled:=true; end; end; '3':case prevchar of 'a','e','o','u','y','i',chr(246),chr(244):key:=chr(251); 'A','E','O','U','Y','I',chr(214),chr(212):key:=chr(219); chr(234),chr(202):begin PostMessage(Editor.handle,WM_CHAR,8,1); PostMessage(Editor.handle,WM_CHAR,ord(prevchar)+16,1); handled:=true; end; chr(226),chr(194):begin PostMessage(Editor.handle,WM_CHAR,8,1); PostMessage(Editor.handle,WM_CHAR,ord(prevchar)+3,1); handled:=true; end; end; '4':case prevchar of 'a','e','o','u','y','i',chr(246),chr(244):key:=chr(245); 'A','E','O','U','Y','I',chr(214),chr(212):key:=chr(213); chr(234),chr(202):begin PostMessage(Editor.handle,WM_CHAR,8,1); PostMessage(Editor.handle,WM_CHAR,ord(prevchar)+18,1); handled:=true; end; chr(226),chr(194):begin PostMessage(Editor.handle,WM_CHAR,8,1); PostMessage(Editor.handle,WM_CHAR,ord(prevchar)+1,1); handled:=true; end; end; '5':case prevchar of 'a','e','o','u','y','i',chr(246),chr(244):key:=chr(239); 'A','E','O','U','Y','I',chr(214),chr(212):key:=chr(207); chr(234),chr(202):begin PostMessage(Editor.handle,WM_CHAR,8,1); PostMessage(Editor.handle,WM_CHAR,ord(prevchar)+1,1); handled:=true; end; chr(226),chr(194):begin PostMessage(Editor.handle,WM_CHAR,8,1); PostMessage(Editor.handle,WM_CHAR,ord(prevchar)+2,1); handled:=true; end; end; '6':case prevchar of 'a','e','o':key:=chr(226); 'A','E','O':key:=chr(194); end; '7':begin if prevchar in ['U','O','u','o'] then begin postmessage(Editor.handle,WM_CHAR,8,1); handled:=true; end; case prevchar of 'u':postmessage(Editor.handle,WM_CHAR,246,1); 'U':postmessage(Editor.handle,WM_CHAR,214,1); 'o':postmessage(Editor.handle,WM_CHAR,244,1); 'O':postmessage(Editor.handle,WM_CHAR,212,1); end; end; '8':case prevchar of 'a':key:=chr(234); 'A':key:=chr(202); end; '9':begin if prevchar in ['D','d'] then begin postmessage(Editor.handle,WM_CHAR,8,1); handled:=true; end; case prevchar of 'd':postmessage(Editor.handle,WM_CHAR,241,1); 'D':postmessage(Editor.handle,WM_CHAR,209,1); end; end; end; prevchar:=key; msg.wparam:=ord(key); end; end; 8. Mã lệnh tạo bộ gõ Tiếng Nga //**Thủ tục đổi mã font procedure DoiMaFont(formTuDien: TfrmNgaVietAnh; MaFont: byte); begin PostMessage(formTuDien.cboNhapTu.handle,WM_CHAR,8,1); PostMessage(formTuDien.cboNhapTu.handle,WM_CHAR,MaFont,1); end; {==============} //** Thủ tục chọn font cho các đối tượng tiếng Nga procedure _ChoseFont(key:char; chose: byte);export;stdcall; begin case key of 'f':DoiMaFont(chose,224); 'F':DoiMaFont(chose,192); ',':DoiMaFont(chose,225); '<':DoiMaFont(chose,193); 'd':DoiMaFont(chose,226); 'D':DoiMaFont(chose,194); 'u':DoiMaFont(chose,227); 'U':DoiMaFont(chose,195); 'l':DoiMaFont(chose,228); 'L':DoiMaFont(chose,196); 't':DoiMaFont(chose,229); 'T':DoiMaFont(chose,197); '/':DoiMaFont(chose,184); '?':DoiMaFont(chose,168); ';':DoiMaFont(chose,230); ':':DoiMaFont(chose,198); 'p':DoiMaFont(chose,231); 'P':DoiMaFont(chose,199); 'b':DoiMaFont(chose,232); 'B':DoiMaFont(chose,200); 'q':DoiMaFont(chose,233); 'Q':DoiMaFont(chose,201); 'r':DoiMaFont(chose,234); 'R':DoiMaFont(chose,202); 'k':DoiMaFont(chose,235); 'K':DoiMaFont(chose,202); 'v':DoiMaFont(chose,236); 'V':DoiMaFont(chose,204); 'y':DoiMaFont(chose,237); 'Y':DoiMaFont(chose,205); 'j':DoiMaFont(chose,238); 'J':DoiMaFont(chose,206); 'g':DoiMaFont(chose,239); 'G':DoiMaFont(chose,207); 'h':DoiMaFont(chose,240); 'H':DoiMaFont(chose,208); 'c':DoiMaFont(chose,241); 'C':DoiMaFont(chose,209); 'n':DoiMaFont(chose,242); 'N':DoiMaFont(chose,210); 'e':DoiMaFont(chose,243); 'E':DoiMaFont(chose,211); 'a':DoiMaFont(chose,244); 'A':DoiMaFont(chose,212); '[':DoiMaFont(chose,245); '{':DoiMaFont(chose,213); 'w':DoiMaFont(chose,246); 'W':DoiMaFont(chose,214); 'x':DoiMaFont(chose,247); 'X':DoiMaFont(chose,215); 'i':DoiMaFont(chose,248); 'I':DoiMaFont(chose,216); 'o':DoiMaFont(chose,249); 'O':DoiMaFont(chose,217); ']':DoiMaFont(chose,250); '}{':DoiMaFont(chose,218); 's':DoiMaFont(chose,251); 'S':DoiMaFont(chose,219); 'm':DoiMaFont(chose,252); 'M':DoiMaFont(chose,220); chr(39):DoiMaFont(chose,253); '"':DoiMaFont(chose,221); '.':DoiMaFont(chose,254); '>':DoiMaFont(chose,222); 'z':DoiMaFont(chose,255); 'Z':DoiMaFont(chose,223); end; end; V.4. GIAO DIỆN CỦA CHƯƠNG TRÌNH VÀ CÁCH THỨC HOẠT ĐỘNG 1. Giao diện chính của chương trình với các menu thành phần Tất cả các chức năng đều được thể hiện rõ trên giao diện chính của chương trình. Từ Form chính, người sử dụng có thể kích chuột để chọn một trong các menu có sẳn. Ứng với từng menu được chọn, Form chính sẽ nối kết đến từng Form DLL tương ứng được tạo sẳn. Mục giới thiệu đề tài và sử dụng chương trình Menu của các từ điển Ngữ pháp tiếng Nga Menu Thực hành: dùng nối kết tới Form luyện nghe hoặc Form làm bài tập trắc nghiệm. Menu Trợ giúp: nối kết tới trang giới thiệu đề tài hoặc trang hướng dẫn sử dụng chương trình. Menu Từ điển: nối kết tới Form Từ điển Nga – Việt hoặc Từ điển Nga – Anh. Menu Ngữ pháp: nối kết tới Form ngữ pháp tiếng Nga. Menu chọn chương trình luyện nghe và làm bài tập 2. Giao diện Từ điển Từ điển gồm các phím chức năng cơ bản như : tra từ, trở về từ trước đó, phần tiện ích với các chức năng: thêm từ, sửa từ, xóa từ. Nhấn nút tra từ sau khi chọn một từ bất kỳ trong danh sách, sẽ xuất hiện nghĩa của từ và hình ảnh (nếu có). Khi gõ từng kí tự vào ô nhập từ, danh sách các từ có kí tự tương ứng được nhảy đến tự động nhằm giúp người sử dụng trong quá trình tra từ. Trở về từ trước: đó giúp người dùng tiết kiệm thời gian trong việc tìm lại nghĩa những từ mình đã tra. Ngoài ra Từ điển còn cung cấp thêm hai nút chức năng: hiển thị bàn phím và thay đổi kích cỡ chữ (có 3 cấp độ: chữ lớn, chữ trung bình và chữ nhỏ). Ô nhập từ Phiên âm (nếu có) Nút tra từ Nút trở lại từ trước đó Form bàn phím được thiết kế như sau: ứng với từng kí tự tiếng Nga sẽ có một kí tự của bàn phím thông thường có kích thước nhỏ hơn ở phía trên bên phải. Bàn phím Tiếng Nga của từ điển. Thayđổi kích cỡ từ Hiển thị bàn phím tiếng Nga Nút tiện ích Từ điển Nga - Việt Từ điển Nga - Anh Nút tiện ích chứa ba chức năng cơ bản ở một từ điển thông thường, đó là: xóa từ, sửa từ, thêm từ. Chọn một trong ba chức năng này thì Form DLL tương ứng sẽ xuất hiện. Với Form xóa từ, chỉ cần nhập từ vào ô xóa từ và click chuột vào nút Xóa thì hoặc là từ sẽ được xóa nếu tìm thấy, hoặc đưa ra thông báo “Không tìm thấy từ trong từ điển”. Để sửa từ, lần lượt gõ từ cần sửa, từ thay thế và nghĩa từ cần sửa vào các ô đã để trống sẳn, rồi nhấn nút Sửa. Nếu được tìm thấy thì từ sẽ được sửa và đưa ra thông báo “Từ đã được sửa xong” ngược lại thì đưa ra thông báo “Không tìm thấy từ trong từ điển”. Để thêm từ, lần lượt nhập từ mới và nghĩa từ mới vào các ô trống, rồi nhấn nút Lưu. Nếu từ đã có trong danh sách, hiển thị thông báo “Từ đã có trong từ điển” ngược lại thì đưa ra thông báo “Từ đã được thêm vào từ điển”. 3. Giao diện Ngữ pháp Giao diện này gồm hai chức năng: một là hiển thị các bài ngữ pháp từ cơ bản đến phức tạp, hai là cho phép người sử dụng in ra bài ngữ pháp đó. Người sử dụng có thể phóng to, thu nhỏ giao diện trong quá trình đọc. Nút hiển thị tiêu đề các bài học Ngữ pháp. Danh sách các bài học ngữ pháp. Nút in bài học tiếng Nga. 4. Giao diện Bài tập Trên giao diện này, người dùng được phép chọn một trong số các bài tập trong danh sách được liệt kê sẳn. Sau khi chọn bài tập thì nhấn nút BẮT ĐẦU để hiển thị câu hỏi và tiếp tục nhấn nút TIẾP THEO để xuất hiện các câu hỏi tiếp theo của bài tập đó. Các bài tập có dạng trắc nghiệm, bên dưới mỗi câu hỏi sẽ có các câu trả lời và người sử dụng chọn ra câu trả lời đúng nhất trong số chúng để đánh dấu vào các ô chọn A, B, C. Chọn xong câu trả lời cho các câu hỏi, người dùng có thể kiểm tra lại câu trả lời của mình bằng cách chọn mục SỬA LỖI hoặc kiểm tra số câu đúng và số câu sai của mình sau khi thực hiện đánh dấu trắc nghiệm bài tập bất kỳ qua mục KẾT QUẢ . Người sử dụng có thể thoát khỏi chương trình bài tập bằng cách bấm THOÁT. Hình ảnh chọn bài tập. Bảng chọn câu trả lời. Mục hiển thị bảng kết quả. Mục sửa lại kết quả đúng. 5. Giao diện Luyện nghe Giao diện cho phép người dùng chọn một trong số các bài nghe được liệt kê trong danh sách để thực hành. Một bài nghe gồm hai chế độ: Nghe đọc và Nghe. Ở chế độ nghe, người dùng chỉ được hỗ trợ về từ vựng trong mục Ghi nhớ và dựa vào lượng từ vựng được cung cấp để đoán nội dung bài đọc. Ngược lại, chế độ Nghe đọc hiển thị cả nội dung bài đọc để người dùng nhận biết được âm của từ hoặc để kiểm tra lại bài đọc sau khi nghe. 6. Trang giới thiệu đề tài Phần V: NHỮNG KHÓ KHĂN, THUẬN LỢI VÀ HƯỚNG PHÁT TRIỂN CHƯƠNG TRÌNH 1. Những khó khăn Khi bắt đầu thực hiện, chương trình gặp phải một số khó khăn sau: - Vì chương trình học Tiếng Nga là một ứng dụng mới nên việc tham khảo về nội dung và kiểu dáng gặp không ít khó khăn. - Một số font tiếng Nga có sẳn không hỗ trợ dấu nhấn trọng âm của từ, do đó trong quá trình sử dụng, người dùng bắt buộc phải chèn thêm dấu này ở font khác. Điều này gây mất thời gian và khó khăn cho người dùng. - Mã kí tự tiếng Nga không theo thứ tự nhất định gây khó khăn cho việc sắp xếp từ trong từ điển. - Việc nhập dữ liệu cho chương trình gặp trở ngại trong việc chuyển đổi bộ gõ giữa tiếng Nga và tiếng Việt. - Cấu trúc con trỏ là kiểu cấu trúc tương đối khó thực hiện khi mới bắt đầu làm quen. - Một hệ thống các bài đọc, bài tập và bài ngữ pháp hoàn chỉnh đòi hỏi một thời gian biên soạn và thu thập lâu dài. 2. Thuận lợi - Hiện nay, ngày càng có nhiều phần mềm ứng dụng rất tiện ích cho quá trình xây dựng hệ thống âm thanh, ảnh dữ liệu, ảnh nền, biểu tượng, font chữ của chương trình. Các phần mềm đó là: Photoshop, Photographer, VcdCutter, JetAudio,.... - Tài liệu về Tiếng Nga tuy cũ nhưng vẫn rất phong phú, đa dạng. - Đề tài được thực hiện dưới sự cố vấn và giúp đỡ của các giáo viên tiếng Nga lâu năm. - Nếu đề tài được hoàn thiện thì nó có thể được ứng dụng rộng rãi, đặc biệt cho các bạn thích thú muốn làm quen với Tiếng Nga, một ngôn ngữ vốn rất phổ biến trước đây, cũng như các bạn sinh viên đang học ngoại ngữ này trong nhà trường ( các trường cao đẳng, đại học trên toàn quốc ). Hiện tại, nếu được thực hiện hoàn tất thì đề tài này sẽ được thử nghiệm tại khoa tiếng Nga trường Cao đẳng Sư phạm Nha Trang, đây là cơ hội để đề tài có thể tiếp tục được chỉnh sửa và hoàn thiện thêm. 3. Hướng khắc phục và phát triển chương trình Để khắc phục những thiếu sót còn lại, cần có một thời gian dài tìm hiểu và thử nghiệm thực tế. Ngoài ra chương trình có thể phát triển thêm: + Một số từ điển như: Từ điển Anh – Nga, Từ Điển Tin Học, Từ điển cơ khí,… . + Các tài liệu ngữ pháp nâng cao kèm theo bài tập ứng dụng. + Các bài nghe với đủ các cấp độ và cho phép người sử dụng đánh giá được trình độ nghe của mình. ......... Phần VII: KẾT LUẬN Có thể nói ngôn ngữ Delphi hỗ trợ hầu hết các kiểu dữ liệu cần thiết cho việc thiết kế cấu trúc một chương trình Từ Điển. Ở đây cấu trúc dữ liệu kiểu con trỏ được sử dụng để thiết lập cấu trúc cây Từ Điển, trong chương trình mỗi nút trên cây có cấu trúc là một bản ghi móc nối gồm 3 trường: Type TNode = ^Node; Node = record Info: char; Left, Right: TNode; End; Đối với dạng cây Từ Điển đã nói ở trên ta thấy cây Từ Điển là một cây dạng tổng quát có tiền tố chung. Nhưng để ở dạng cây tổng quát thì việc thực hiện các thao tác và các phép xử lý trên cây khó khăn, cho nên cây được chuyển về dạng cây nhị phân với thuật toán chuyển đã trình bày. Qua dạng cấu trúc của cây nhị phân Từ Điển ta có nhận xét chung: Một từ luôn được kết thúc trên nhánh cây con trái. Các từ có tiền tố chung khi chúng là cây con phải của nút con trái của nút chứa kí tự cuối cùng thuộc chuỗi tiền tố. Từ nhận xét trên chúng ta có thể xây dựng được các giải thuật tìm kiếm, thêm, loại bỏ… một cách chính xác. Trong chương trình, các giải thuật được thực hiện theo Heuristic nhằm tránh lỗi tràn bộ nhớ mà các giải thuật đệ qui mắc phải, tuy nhiên các phương pháp thực hiện giải thuật này có thể không nhanh bằng giải thuật đệ qui. Hầu hết các form được xây dựng từ Form DLL nên quá trình nối kết giữa các Form rất thuận tiện, nhanh chóng. Thêm vào đó, sự hỗ trợ của các hàm, thủ tục DLL trong quá trình biên dịch làm chương trình chính vì thế mà linh hoạt hơn. Trong thời gian thực tập vừa qua chương trình đã đạt được một số kết quả khả quan, mong rằng trong thời gian tới cùng sự giúp đỡ, góp ý của các thầy cô và các bạn, chương trình sẽ được chỉnh sửa để ngày càng hoàn thiện. TÀI LIỆU THAM KHẢO [1] “Cấu trúc dữ liệu và giải thuật” – Đỗ Xuân Lôi – Nhà xuất bản khoa học và kỹ thuật. [2] “Nhập môn thuật toán và cấu trúc dữ liệu” – J.Courtin I.Kowarski – do nhóm tác giả: Đào Nam Anh, Trần Đình Quế, Phạm Ngọc Khôi dịch và hiệu đính. [3] “Lập trình nâng cao với các kiểu dữ liệu cấu trúc của PASCAL” (2 tập) – N.Wirth – do Lê Minh Trung dịch. [4] “Cấu trúc dữ liệu” – Nguyễn Trung Trực – Trường Đại Học Bách Khoa TP.HCM. [5] “Cẩm nang thuật toán” – Tập 1: “Các thuật toán thông dụng” – Robert Sedgewick – Nhà xuất bản khoa học và kỹ thuật. [6] Tập san “Tin học và nhà trường” – Số 1-2 (40 - 41). [7] “Giáo trình lý thuyết và bài tập Borland DelPhi” – Lê Phương Lan & Hoàng Đức Hải – Nhà xuất bản giáo dục. [8] “Các kỹ xảo lập trình với Microsoft Visual Basic và Borland Delphi” – Lê Hữu Đạt (Chủ biên)– Nhà xuất bản giáo dục. [9] “Nhập môn cấu trúc dữ liệu và giải thuật” – Trần Hạnh Nhi, Dương Anh Đức, Hoàng Kiếm – Đại học Khoa Học Tự Nhiên

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

  • dochttn-cthtn.doc
Tài liệu liên quan