Cấu trúc dữ liệu trừu tượng (ADT)
Trang 1VIỆN CÔNG NGHỆ THÔNG TIN VÀ TRUYỀN THÔNG
──────── * ───────
BÀI TẬP LỚN
MÔN: KỸ THUẬT LẬP TRÌNH
NHÓM 03
Sinh viên thực hiện : Trần Ngọc Thái
Đinh Văn Chinh Nguyễn Văn Mạnh Bùi Thị Lệ Quyên Nguyễn Mạnh Tuấn
Lớp : CNTT3,4,5 – K55 Giáo viên hướng dẫn : TS Vũ Thị Hương Giang
Trang 2Hà Nội, tháng 5 năm 2012
Trang 3MỤC LỤC
MỤC LỤC 3
LỜI NÓI ĐẦU 4
PHÂN CÔNG THÀNH VIÊN TRONG NHÓM 5
Viết báo cáo, tài liệu chương trình 5
PHÂN TÍCH YÊU CẦU VÀ THIẾT KẾ GIẢI PHÁP 6
CHƯƠNG 1 CÀI ĐẶT CHƯƠNG TRÌNH 14
TÀI LIỆU THAM KHẢO 28
PHỤ LỤC 29
Trang 4LỜI NÓI ĐẦU
Trong thời gian đầu học tập tại viện Công nghệ thông tin và truyền thông của đại học Bách khoa Hà Nội, chúng em đã được học và tiếp xúc với một số môn cơ sở ngành trong đó có môn Kỹ thuật lập trình Học phần này được giảng dạy với mục đích giúp sinh viên có được các kiến thức cơ bản của kỹ thuật lập trình, có khả năng phân tích, xây dựng chương trình, làm chủ các kỹ thuật: viết mã hiệu quả, gỡ rối, đánh giá chương trình Việc thực hiện bài tập lớn lần này đã tạo cơ hội để chúng em áp dụng những kiến thức đã học đó trong môn kĩ thuật lập trình để xây dựng một chương trình hoàn chỉnh
Bài tập lớn có chủ đề về việc tạo một cấu trúc dữ liệu trừu tượng (ADT) gồm 2 thành phần: mảng các số thực và số lượng gái trị lưu trữ trong mảng; ADT cho phép thực hiện một số thao tác sắp xếp, tìm kiếm, thống kê…, bên cạnh đó bài toán cũng yêu cầu viết một chương trình cung cấp các chức năng để kiểm tra ADT đó
Để có thể tiến hành bài tập này, trước hết, nhóm đã tìm hiểu để nắm vững yêu cầu của đề bài, phân tích các yêu cầu ẩn và hiện của bài toán, trong đó đặc biệt chú trọng đến khái niệm thế nào là một ADT cũng như các thuộc tính của nó Bước tiếp theo là thiết kế giải pháp, trong bước này chúng em đã chia bài toán thành các phần nhỏ hơn, thiết kế giải thuật phù hợp cho mỗi phần, việc thiết kế được tuân thủ theo phương thức thiết kế top-down Sau đó, nhóm tiến hành cài đặt thiết kế trên cơ sở các giải thuật được lựa chọn ở trên, trong quá trình vừa viết mã nguồn, chúng em vừa tiến hành kiểm tra Khi cài đặt xong chương trình, nhóm thực hiện việc chạy thử và kiểm tra tổng thể chương trình, tìm và sửa các lỗi để đảm bảo cho chương trình chạy thông
và chạy đúng trong các tình huống khác nhau Khi chương trình đã chạy thông và đúng, chúng em tiến hành tinh chỉnh mã nguồn, để đảm bảo mã nguồn là tối ưu, thời gian chạy được rút ngắn nhiều nhất có thể Sau khi đã hoàn thiện chương trình, nhóm tiến hành viết tài liệu cho chương trình
Vì đây là bài tập lớn đầu tiên yêu cầu sử dụng tất cả các kĩ thuật đã học cùng với việc chúng em chưa có nhiều kinh nghiệm lập trình nên dù đã cố gắng rất nhiều, song trong quá trình thực hiện bài tập lớn vẫn còn nhiều thiếu sót, kính mong cô giáo
và các bạn nhận xét và đóng góp ý kiến để chúng em có thể hoàn thiện hơn nữa chương trình của mình
Cuối cùng, chúng em xin chân thành cảm ơn TS Vũ Thị Hương Giang đã hướng dẫn để nhóm có thể hoàn thành bài tập lớn này
Trang 5PHÂN CÔNG THÀNH VIÊN TRONG NHÓM
Trên cơ sở bài tập tuần 5 đã nộp xây dựng bài tập lớn với các modul, tài liệu báo cáo Phân công công việc như sau:
Viết chương trìnhTên công việc Người thực hiện Thời gianTạo modul Array.h, hamphu.h,menu.h Tuấn 14/04/2012
Tao modul nhapxuat.h, sapxep.h Mạnh 14/04/2012
Tạo modul minmax.h,thongke.h Thái 14/04/2012
Tạo modul timkiem.h,dpt.h Chinh 14/04/2012
Tạo Checkarray.cpp, các bộ dữ liệu Quyên 14/04/2012
Ghép các modul để chạy thử 15-16/04/2012
Testing, phát hiện lỗiTên công việc Người thực hiện Thời gianChức năng 1,2,13,14 Tuấn 17/04/2012Chức năng 3,4,5 Thái 17/04/2012Chức năng 6,7 Chinh 17/04/2012Chức năng 8,9,10 Quyên 17/04/2012Chức năng 11,12 Mạnh 17/04/2012Tổng hợp lỗi, tiến hành hiệu chỉnh, sửa
Tổng hợp chương trình hoàn chỉnh 20/04/2012Viết báo cáo, tài liệu chương trình
Tên công việc Người thực hiện Thời gian
Lời nói đầu, biểu đồ IPO 4 chức năng
đầu,các kĩ thuật đã áp dụng(2 mục đầu) Quyên 22/04/2012
Biểu đồ IPO 10 chức năng tiếp,kết quả
chương trình 8 chức năng đầu Tuấn 25/04/2012
Mục thiết kế chương trình, kết quả
chương trình 6 chức năng tiếp
Chinh 25/04/2012
Thiết kế giải thuật, các kĩ thuật xây dựng
chương trình, các kĩ thuật viết mã nguồn
hiệu quả
Thái 24/04/2012
Thiết kế dữ liệu, phong cách lập trình Mạnh 23/04/2012
Giao diện chương trình Thái, Chinh 23/04/2012
Kết luận và hướng phát triển Quyên, Mạnh 25/04/2012
Trang 6PHÂN TÍCH YÊU CẦU VÀ THIẾT KẾ GIẢI PHÁP
Yêu cầu chương trình:
Bài toán yêu cầu tạo một ADT có tên là Array và lưu trữ trong file Array.h
ADT này bao gồm 2 thành phần thông tin:
+ Max: mảng các giá trị số thực
+ count: số lượng các giá trị lưu trữ trong mảng Max
ADT này cho phép thực hiện một số thao tác trên mảng số thực:
I .Khởi tạo một phiên bản mới của chính nó
ii Gán giá trị cho các thành phần thông tin của một đối tương Array
iii Sắp xếp các phần tử của mảng theo giải thuật bubble sort
iv Sắp xếp các phần tử của mảng theo giải thuật insertion sort
v Sắp xếp các phần tử của mảng theo giải thuật selection sort
vi Tìm giá trị lớn nhất được lưu trữ trong mảng và vị trí của các phần tử có giá trị lớn nhất trong mảng
vii Tìm giá trị nhỏ nhất được lưu trữ trong mảng và vị trí của các phần tử có giá trị nhỏ nhất trong mảng
viii Tìm giá trị trung bình của các phần tử trong mảng
ix Tìm độ lệch về giá trị giữa 2 phần tử có vị trí biết trước trong mảng
x Tìm độ lệch trung bình về giá trị của các phần tử trong mảng
xi Tìm kiếm (theo giải thuật sequential search) phần tử của mảng có giá trị là x ; nếu tìm thấy thì đưa ra vị trí của phần tử đó trong mảng, nếu không thì trả lại giá trị
là 0
xii Tìm kiếm (theo giải thuật binary search) phần tử của mảng có giá trị là x ; nếu tìm thấy thì đưa ra vị trí của phần tử đó trong mảng, nếu không thì thông báo là không tìm thấy phần tử như vậy
xiii Biểu diễn độ phức tạp tính toán theo ký pháp big-O và hiện thị thời gian tính toán thực tế bằng micro-second
Cùng với đó, bài toán cũng yêu cầu viết một chương trình cung cấp các chức năng để kiểm tra ADT này; chương trình được lưu trữ trong file CheckArray.cpp Hàm menu() : gồm các tùy chọn
1-13: các chức năng tính toán trên mảng
Tùy chọn 1: có menu con cho phép
Nạp thông tin vào từ bàn phím hoặc từ 1 file dữ liệu vào/ra (I/O data file)
Quay lại menu chính
Tùy chọn 2-13: có menu con cho phép
In kết quả ra màn hình hoặc ra 1 file dữ liệu vào/ra (I/O data file)
Quay lại menu chính
14: thoát khỏi chương trình
Trang 70.1 Biểu đồ IPO
0.1.1 Chức năng 1: khởi tạo một phiên bản của chính nó
Mảng cũ Khởi tạo Mảng mới
0.1.2 Chức năng 2: Nhập các giá trị cho các phần tử trong mảng
Các nguồn dữ liệu vào Lựa chọn Cách nhập dữ liệu
Dữ liệu Đọc dữ liệu
Gán giá trị cho các phần tử của mảng
Mảng đã được gán giá trị Tìm kiếm min (max) Min (max)
Tìm kiếm vị trí min (max) vị trí min (max)Các cách xuất dữ liệu Lựa chọn 1 cách xuất dữ liệu
Tổng, số phần tử Chia trung bình Trung bình
Các cách xuất dữ liệu Lựa chọn 1 cách xuất dữ liệu
In kết quả
1.2.9 Chức năng 9
Trang 8Nhập vào vị trí 2 phần tử bất kỳ
Tính độ lệch và in ra màn hình hoặc file
Vị trí x1, vị trí x2 Đọc vào Hai vị trí
Max[x1],Max[x2] Tính hiệu hai giá trị Hiệu
Hiệu Lấy trị tuyệt đối Độ lệch
Các cách xuất dữ liệu Lựa chọn 1 cách xuất dữ liệu
Tổng1, số phần tử Chia trung bình Trung bình
Các phần tử, trung bình Lấy hiệu Hiệu
Hiệu Lấy trị tuyệt đối Độ lệch các phần tử
Thực hiện tìm kiếm nhị phân
In ra vị trí các phần tử tìm được ra màn hình hoặc file
Mảng được gắn giá trị Sắp xếp Mảng được sắp xếpMảng được sắp xếp Tìm kiếm nhị phân Phần tử cần tìm Các cách xuất dữ liệu Lựa chọn 1 cách xuất dữ liệu
In kết quả1.2.12 Chức năng 12
Trang 9Thực hiện tìm kiếm nhị phân
In ra vị trí các phần tử tìm được ra màn hình hoặc file
Mảng chứa các phần tử Tìm kiếm tuần tự Phần tử cần tìm Các cách xuất dữ liệu Lựa chọn 1 cách xuất dữ liệu
In kết quả
1.2.13
Tính thời gian thực hiện chương trình
In ra màn hình hoặc file
Điểm bắt đầu, điểm kết thúc Lấy hiệu Hiệu số chu kì
Hiệu số chu kì, số chu kì/1s chia Số s
Trang 10Cấu trúc phân cấp chương trình: dựa vào các chức năng mà chương trình chính được chia làm nhiều modul khác nhau Chương trình chính chỉ chứa các lệnh gọi tới các
hàm trong modul
Chương trình được chia làm các modul
O U T P U T
Bàn phímfile
độ phức tạp
Tìm kiếm
Các giá trị đặc trưng
Bubble sortInsertion sortSelection sort
Thời gian tính toánBinary search
Sequential search
Độ lệch trung bình, độ lệch
giữa 2 phần tửGiá tri trung bình
Giá tri min,max
Độ phức tạp của thuật toán
Trang 111 Modul nhapxuat.h:
Chứa hàm khoi_tao(),nhap_mang(), in_mang() và sfree()
Thực hiện chức năng nhập dữ liệu từ bàn phím hoặc file, đồng thời thực hiện chức năng xuất dữ liệu ra màn hình hoặc file, thực hiện giải phóng dữ liệu
- Do_lech_tb(): tính độ lệch trung bình của mảng
- gttb(): tính giá trị trung bình các phần tử của mảng
7 Modul timkiem.h
Chứa các chương trình tìm kiếm:
- Sequential_search(): tìm kiếm tuần tự
- Binary_search(): tìm kiếm nhị phân
Cụ thể thiết kế dữ liệu như sau:
• Khai báo các phương thức (thao tác) trên lớp như sau:
- int menu() – Bảng menu chính
- int menu2() – Bảng menu phụ thực hiện chức năng 13
- int menu3() – Bảng menu thực hiện hiển thị kết quả
- void khoi_tao() – chương trình khởi tạo một mảng mới
- void nhap_mang() – chương trình nhập các phần tử của mảng
- void in_mang() – chương trình in ra các phần tử của mảng sau khi sắp xếp
- void Bubble_sort() – Thuật toán sắp xếp nổi bọt
Trang 12- void Insertion_sort() – Thuật toán sắp xếp chèn
- void Selection_sort() – Thuật toán sắp xếp lựa chọn
- void max() – chương trình tìm phần tử lớn nhất và vị trí trong mảng
- void min() - chương trình tìm phần tử nhỏ nhất và vị trí trong mảng
- int kt() – hàm trả về số lượng các phần tử trong mảng
- void gttb() – chương trình tính giá trị trung bình các phần tử của mảng
- void do_lech() – chương trình tính độ lệch hai phần tử của mảng
- void do_lech_tb() – Chương trình tính độ lệch trung bình các phần tử của mảng
- void Sequential_search() – Thuật toán tìm kiếm tuần tự
- void Binary_search() – Thuật toán tìm kiếm nhị phân
- void Dpt() – Chương trình đưa ra độ phức tạp và thời gian tính toán
- void swap(float &a,float &b) – đổi chỗ hai phần tử của mảng
- void sfree() – giải phóng bộ nhớ
• Để lưu lại mảng ban đầu (tránh trường hợp mảng bị thay đổi sau khi sắp xếp): tạo thêm một mảng số thực B copy lại mảng A sau khi nhập dữ liệu vào
• Tạo các biến start_Bubble, finish_Bubble, start_Insertion,… để phục vụ tính thời gian
• Các chức năng được nhóm lại trong các modul để phân biệt với nhau Có các modul như sau:
Được chia ra làm 3 công việc chính:
- Sắp xếp mảng theo chiều không giảm
- Tìm kiếm giá trị x trong mảng bằng Binary search
- In ra các phần tử có giá trị x
Cụ thể như sau
1 Sắp xếp các phần tử theo chiều không giảm
Trang 13Sử dụng thuật toán Bubble sort để thực hiện sắp xếp các phần tử của mảng Max theo chiều không giảm.
Tuy nhiên sau khi sắp xếp thì vị trí các phần tử không còn như trước nữa nên nếu thực hiện tìm kiếm sẽ dẫn đến kết quả không chính xác, do đó tạo một mảng b lưu vị trí ban đầu của các phần tử mảng Max, như vậy khi thực hiện tìm kiếm sẽ chỉ cần đưa
ra các phần tử mảng b
2 Thực hiện tìm kiếm nhị phân
Tạo thêm 1 mảng là mảng c để lưu vị trí các phần tử có giá trị x (như vậy sẽ tiện hơn khi in kết quả ra file và ra màn hình)
Tạo các biến l,r,m để lưu vị trí đầu mảng, cuối mảng và giữa mảng
Thực hiện so sánh giá trị phần tử giữa mảng với giá trị cần tìm kiếm Có 3 trường hợp:
- Nếu Max[m]>x, tức là phần tử cần tìm kiếm ở bên trái phần tử m, thực hiện tìm kiếm nhị phân với nửa trái của mảng
- Nếu Max[m]<x, tức là phần tử cần tìm kiếm ở bên phải phần tử m, thực hiện tìm kiếm nhị phân với nửa phải của mảng
- Nếu Max[m]=x, phần tử m là phần tử có giá trị x
Ở trường hợp cuối mặc dù đã tìm được vị trí m có giá trị x nhưng có thể các phần tử bên cạnh m cũng có giá trị x (do phần tử x không phải là duy nhất, và mảng xếp theo chiều không giảm) do đó tạo 2 biến t va p (t =m-1, p=m+1) để xét các phần tử lân cận
m Nếu các phần tử này cũng có giá trị x thì lưu vị trí các phần tử này vào mảng c Như vậy sau bước này ta đã có vị trí tất cả các phần tử có giá trị x
3 In vị trí các phần tử
Trước khi in vị trí các phần tử cần làm 2 việc:
- Trả lại vị trí ban đầu cho các phần tử của mảng Max(bằng cách dùng mảng B)
- Sắp xếp lại các phần tử mảng c để kết quả in ra theo chiều tăng dần về vị tríSau đó thực hiện in kết quả
Trang 14CHƯƠNG 1 CÀI ĐẶT CHƯƠNG TRÌNH
1.1 Các kỹ thuật lập trình đã áp dụng
<Liệt kê các kỹ thuật lập trình đã sử dụng để làm bài tập lớn >
STT Mô tả kỹ thuật / quy tắc Mô tả đối tượng áp dụng (hàm,
biến, biểu thức, câu lệnh) và phạm vi áp dụng
Các biến tính thời gian:
start_Bubble,finish_Bubble, count… được sử dụng trong toàn
bộ chương trình nên là biến toàn thể
Các biến đặc trưng cho từng chương trình con thì chỉ khai báo
+ Dùng kiểu double khi cần kết quả có độ chính xác cao
+Dùng kiểu int cho các biến chỉ số
+Ví dụ như biến dl (biến lưu tổng
độ lệch các phần tử), biến kq (lưu kết quả độ lệch trung bình giữa các phần tử)…
+ Ví dụ i(dùng làm chỉ số chạy khi duyệt các phần tử của mảng)
…
4 Sử dụng các biến trung gian để phân biệt các bước tính toán
VD: Ví dụ biến cục bộ temp trong phần nhapxuat.h (biến trung gian lưu giá trị phần tử đọc vào), biến cục bộ temp lưu giá trị trung gian của phần sắp xếp…
5 Khởi tạo giá trị ban đầu
cho biến
VD: các biến đếm được khởi tạo giá trị ban đầu la 0, các biến tính tổng được khởi tạo giá trị ban đầu
+Viết dấu mở ngoặc nhọn ngay sau câu lệnh
+Sử dụng các khoảng cách hợp lý để dễ đọc các câu
Mã nguồn chương trình
Trang 152 -Lựa chọn cấu trúc lặp hợp lý: đối với vòng lặp biết trước số lần lặp dùng vòng lặp for, nếu không biết trước số lần lặp dùng vòng lặp while hoặc do…while
-VD: trong các hàm sắp xếp, do biết trước số lượng phần tử cần duyệt nên sử dụng vòng lặp for, ngược lại trong hàm
nhapxuat(),khi đọc dữ liệu từ file, chưa biết số lượng phần tử nên dùng vòn lặp while
Tránh sử dụng vòng lặp goto
VD: modul: sapxep.h chứa các hàm sắp xếp như Bubble_sort, Insertion_sort,…
Trong chương trình không sử dụng vòng lặp goto
2 Chia bài toán ra thành nhiều bài toán nhỏ hơn rồi giải quyết từng bài toán nhỏ
VD: chức năng tìm kiếm nhị phân được chia ra thành 3 bài toán nhỏ:
+ Sắp xếp mảng theo chiều không giảm
+Tìm kiếm nhị phân+In kết quả
3 Thiết kế theo kiểu
Top-down Thiết kế toàn bộ chương trình một cách sơ bộ rồi mới đi vào chi
Tạo hàm mới do người lập trình định nghĩa
VD hàm fabs() để tính độ lệch giá trị 2 phần tử
Vd: hàm swap() hoán đổi vị trí 2 phần tử
2 Sử dụng tham số kiểu tham chiếu
VD hàm đổi chỗSwap(float &a, float &b)
3 Đặt tên hàm và thủ tục
ngắn gọn có tính chất gợi nhớ
Đặt tên tham số không trùng tên biến
VD: hàm nhap_mang(), in_mang(), khoi_tao()…
quả như: kq, gttb,dl…
2 Không thay đổi tham số của các hàm, không thay đổi mục đích ban đầu của các hàm
Trang 163 Đảm bảo các lỗi buffer
overflows, divide for zero không xảy ra
4 Đảm bảo giá trị các biến
luôn trong vùng kiểm soát
11 Tìm kiếm theo Sequential
search 3 Chinh: cài đặtMạnh: kiểm thử
12 Tìm kiếm theo Binary search 3 Chinh: cài đặt
Mạnh: kiểm thử
13 Biểu diễn độ phức tạp và thời
gian tính toán 3 Chinh: cài đặtThái: kiểm thử
Thái: kiểm thử