Upload
to-trong-hien
View
3.041
Download
3
Embed Size (px)
Citation preview
SSSTTTAAACCCKKK AAA
Bài tập lớ
B
Thành
Giáo v
AAADDDTTT
ớn môn cấu
TRƯỜ
BÀI T
viên: 1. Tô2. N3. Ph4. N5. Tr
viên hướn
trúc dữ liệu
ỜNG ĐKHOA
TẬP LỚCh
ô Trọng HNguyễn Đìn
han Huy TNguyễn Việ
rần Thanh
ng dẫn: Ng
và giải thuậ
ẠI HỌCA CÔNG
ỚN CThủ đề: S
iến (nhómnh Minh Tùng ệt Phương
Tùng
guyễn Đứ
Trang 1
ật Gi
C BÁCHNGHỆ T
TDL VSTACK
m trưởng)
ức Nghĩa
Hà
áo viên hướ
H KHOATHÔNG
À GIẢK ADT
Nội Ngày
ớng dẫn : Ng
A HÀ NTIN
ẢI THU
20/12/200
guyễn Đức N
NỘI
UẬT
07
Nghĩa
SSSTTTAAACCCKKK AAADDDTTT Trang 2
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
Mục lục
1 Giới thiệu trương trình ...................................................................................... 1 1.1 Định nghĩa ADT(Abstract Data Type) ........................................................ 2
1.2 Định nghĩa Stack và các phép toán cơ bản ................................................... 5 1.3 Đối tượng cất giữ .......................................................................................... 7
1.3.1 Stack dùng mảng ....................................................................................... 7 1.3.2 Mở rộng stack dùng mảng ......................................................................... 9 1.3.3 Stack dùng DSLK .................................................................................... 10
1.4 Các ứng dụng của Stack ............................................................................. 13
2 Cài đặt (trên C). ............................................................................................... 13
2.1 Mô phỏng hoạt động của stack ................................................................... 13
2.2 Bài toán chuyển đổi giữa các cơ số ............................................................ 15
2.3 Polish Problem ( bài toán Balan) ............................................................... 20 2.3.1 Cơ sở lý thuyết ......................................................................................... 20 2.3.2 Biểu thức hậu tố và tiền tố ....................................................................... 21 2.3.3 Tính giá trị biểu thức hậu tố .................................................................... 22 2.3.4 Giải thuật tính BTHT............................................................................... 22 2.3.5 Chuyển đổi trung tố sang hậu tố .............................................................. 24 2.3.6 Giải thuật chuyển BTTT sang dạng hậu tố ............................................. 25 2.3.7 Cài đặt giải thuật ...................................................................................... 25
2.4 Một số bài toán khử đệ quy (Derecursion ) ............................................... 32 2.5 Đóng gói stack bằng lớp(Class) trong C++. ............................................... 36
SSSTTTAAACCCKKK AAADDDTTT Trang 3
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
3 Ứng dụng ........................................................................................................... 37 3.1 Phát bểu bài toán ứng dụng ...................................................................... 37
3.2 Mô tả, đánh giá độ phức tạp của giải thuật .............................................. 39
3.3 Mô tả cài đặt trương trình ......................................................................... 40 3.4 các ví dụ ................................................................................................................................. 41
4 Kết luận .............................................................................................................. 45
1. Giới thiệu trương trình: Tất cả các phần thầy giáo yêu cầu chúng em xin được trình bày chi tiết để cho tất cả các bạn không làm về phần này nếu đọc thì đều có thể hiểu được. Bài Tập Lớn (BTL) được chia làm 3 phần: Phần 1 giới thiệu về kiểu dữ liệu trừu tượng - Abstract Data Type(ADT); định nghĩa về ADT Stack cùng với đối tượng cất giữ, các phép toán cơ bản, và một số ứng dụng của stacks trong thực tế. Phần 2 nêu các thao tác cài đặt stack như dùng mảng, dùng danh sách liên kết. phần này có kèm theo các ví dụ minh họa như: dùng stack để chuyển đổi cơ số; dùng stack để chuyển đổi từ dạng biểu thức trung tố sang hậu tố, và tính biểu thức hậu tố. Hay có thể dùng cấu trúc stack để khử các bài toán đệ quy với mục đích tối ưu hóa trương trình. Trong mục cuối phần 2 có phần mở rộng cài đặt stack trên C++ bằng cách đóng gói các dữ liệu và phương thức của stack vào một lớp có tên là CStack và thao tác trên lớp này.( tất cả các mục đều có ví dụ hoàn chỉnh). Phần 3 giới thiệu hai trương trình khá công phu có ứng dụng tất cả các kiến thức nêu trên(lập trình trên C++ 3.0). Trương trình lớn nhất là Calculator mô phỏng máy tính điện tử “CASIO fx 570 Nature Display” với giao diện đồ họa kết hợp sử dụng đồng thời cả chuột và bàn phím(~180KB). Trương trình thứ hai Derivation tính đạo hàm của một hàm số Y=F(X) bất kì(~40KB). Một trương trình lớn thường kết hợp nhiều kiểu cấu trúc dữ liệu(CTDL); để trương trình lớn được đầy đủ chúng em đã nghiên cứu thêm một số CTDL khác như danh sách liên kết (DSLK) kép (Double Linked List), hay cây nhị phân (Binary Tree) . Trương trình Calculator sử
SSSTTTAAACCCKKK AAADDDTTT Trang 4
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
dụng DSLK kép để lưu kết quả của các phép tính trước, và trương trình Derivation sử dụng CDTL kiểu cây để lưu kết quả của phép tính đạo hàm…. Phần lõi của Calculator là các hàm tính biểu thức áp dụng thuật toán Balan(ứng dụng stack); còn phần lõi của Dirivation là thao tác trên cây như có vận dụng CTDL stack trong việt chuyển biểu thưc sang dạng cây để lưu trữ. Cả hai bài toán trên lấy ý tưởng trong cuốn Cấu Trúc Dữ Liệu Và Giải Thuật của thầy Đỗ Xuân Lôi. “Nhóm tác giả xin cam đoan tất cả mọi cài đặt nêu ra là do dầy công suy nghĩ chứ không phải copy hay trích dẫn từ bất kì nguồn tài liệu nào”.
1.1 Định nghĩa ADT(Abstract Data Type)
Dữ liệu từ trước đến nay chúng ta xem sét đều rất cụ thể; ví dụ như kiểu dữ liệu(KDL) Boolean là một tập hợp hai giá trị TRUE và FALSE và các phép toán trên nó như là OR, AND, NOT… Do đó ta có thể định nghĩa KDL là một tập hợp các giá trị và một tập hợp các phép toán trên tập giá trị đó. Có hai loại KDL: KDL sơ cấp và KDL có cấu trúc hay còn gọi là cấu trúc dữ liệu. KDL sơ cấp như Boolean, Integer, Bouble… KDL có cấu trúc như SET, ARRAY, STRUCT… Khác với các kiểu dữ liệu cụ thể trên, Một kiểu dữ liệu trừu tượng(ADT) là một mô hình toán học cùng với một tập hợp các phép toán (operator) trừu tượng được định nghĩa trên mô hình đó. Ví dụ tập hợp số nguyên cùng với các phép toán hợp, giao, hiệu là một kiểu dữ liệu trừu tượng. ADT là sự tổng quát hóa từ các kiểu dữ liệu nguyên thủy. ta có thể phân biệt ADT với CTDL bằng một so sánh sau: các CTDL đã được xây dựng thì thường cho một ngôn ngữ nào đó, chẳng hạn như Pascal hay C…việc chuyển đổi từ một CTDL từ một ngôn ngữ này sang một ngôn ngữ khác là khá vất vả lại ít mang giá trị kinh tế. Do đó người ta đã nghĩ ra một phương pháp là trừu tượng hóa dữ liệu cũng như trương trình để tương thích với gần như tất cả các ngôn ngữ, tiện lợi cho việc cài đặt vào bất cứ một ngôn ngữ lập trình nào. Do đó trương trình viết cho ADT được viết bằng giả ngôn ngữ.
SSSTTTAAACCCKKK AAA
Bài tập lớ
Tác dụnhơn và drất tiện đặt mộtthực hiệ
1. Bd
2. Vt
Ở nhữnADT làhay tổngđi rất nhSau đây
1.2 b
1. ĐịnNgăn xếbổ xungđỉnh (To Ta có thMuốn thchồng, mđĩa trênvà “vào 2. Các
Nhưnó. Ta c
AAADDDTTT
ớn môn cấu
ng của trìu dễ hiểu hơlợi khi ta m
t kiểu dữ liện hai nhiệBiểu diễn kdữ liệu trừViết các chtượng mà tg ngôn ngữ rất rõ rệt. g quát hơnhiều. Nó đey ta tập chu
Định nghbản
nh nghĩa ngếp (Stack) g và loại bỏop) của nó
hể xem hìnhêm vào chmuốn lấy c trước. Nh
o trước ra
phép toán
ư đã định ncó thể xem
trúc dữ liệu
tượng hóaơn. Cụ thể nmuốn cài đệu trừu tượệm vụ: kiểu dữ liệừu tượng khhương trìnhta thường gữ lập trình Ở đó ADT
n là các đốiem lại cho ung đi sâu
hĩa Stack
găn xếp (stalà một danỏ phần tử
ó.
nh ảnh trựchồng đó 1 các đĩa ra k
hư vậy ngăna sau“ (LIF
cơ bản trê
nghĩa một Am một Stack
và giải thuậ
a là làm chonó che đi cđặt một giảợng trên m
ệu trừu tượhác đã đượh con thực gọi là cài đhướng đối
T được đóni tượng, nhcác trương
vào Stack
k và các p
ack) nh sách tuyluôn được
c quan của đĩa ta để đ
khỏi chồngn xếp là mộFO (last in
ên ngăn xếp
ADT đượck ADT bởi
Trang 5
ật Gi
o trương trcác chi tiết ải thuật cho
một ngôn ng
ợng bằng mợc cài đặt.
hiện các pđặt các phéi tượng nhng gói thànhờ đó việc tg trình mộADT.
phép toán
yến tính màc thực hiện
ngăn xếp bđĩa mới trêng ta cũng pột cấu trúcn - first out
p
c định nghĩi các phép
áo viên hướ
rình trở nênvà làm nổ
o một ngôngữ lập trình
một cấu trú
phép toán tép toán. ư C++ hay
nh các trươthao trên ct khả năng
n cơ
à phép ở
bằng một cn đỉnh
phải lấy c có tính cht ). (hình 1
ĩa bởi các ptoán sau:
ớng dẫn : Ng
n đơn giảnổi bật lên cán ngữ bậc ch cụ thể, ch
úc dữ liệu
trên kiểu d
y Java việcơng trình cocác ADT đưg mở rộng r
chồng đĩa đ
hất “vào sa)
phép toán t
Hình 1: cơ cấ
guyễn Đức N
n hơn, sángái tông thểcao. Khi càhúng ta ph
hoặc một
dữ liệu trừu
c ứng dụngon, các lớpược đơn girất lớn.
đặt trên bà
au ra trư
thao tác trê
ấu ngăn xếp
Nghĩa
g sủa nên
ài hải
kiểu
u
g p iản
n.
ước”
ên
SSSTTTAAACCCKKK AAADDDTTT Trang 6
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
• MakeNull (S): tạo ra một stack rỗng mới.
• Top(S): trả về phần tử tại đỉnh stack. Nếu ngăn xếp rỗng hàm không xác định.
• Push(S,x): thêm một phần tử x vào đỉnh stack.
• Pop(S): lọai bỏ phần tử ở đỉnh stack. • IsEmpty(S): kiểm tra stack có rỗng hay
không? Hàm cho kết quả 1 nếu rỗng, còn 0 nếu ngược lại. Các thao tác trên không phụ thuộc vào cách lưu trữ stack bằng mảng hay bằng DSLK. Với 5 phép toán trên ta đã xây dựng nên một mô hình toán học gọi là một kiểu dữ liệu trừu tượng stack. Ta sẽ thao tác với ADT này qua môt ví dụ nhỏ. Ví dụ: Viết chương trình con Reverse_String nhận một chuỗi kí tự từ bàn phím cho đến khi gặp kí tự # thì kết thúc việc nhập và in kết quả theo thứ tự ngược lại. void Reverse_String () {
Stack S; char c; MakeNull(S); // Tạo một stack rỗng Do {
c=getche(); Push(S,c); // Lưu từng ký tự vào ngăn
xếp }while (c!='#'); printf("\nChuoi theo thu tu nguoc lai\n"); while (!IsEmpty(S)) // Khi stack không rỗng {
printf("%c\n",Top(S)); // Lấy phần tử ở đỉnh stack Pop(S); // lọai bỏ một phần tử ở đỉnh
stack }
} Trương trình trên tuy nhỏ nhưng đã sử dụng tất cả các phép toán cơ bản về stack. Như đã nói từ trước, khi thiết kế giải thuật ta có thể dùng các phép toán trừu tượng
Hình 2: Bài toán tháp cờ Hà Nội
SSSTTTAAACCCKKK AAA
Bài tập lớ
như là cTuy nhitrúc dữ cất giữ t
1.3 Đ
1.3. Lưu trữstack (làphần tử giảm đi Ta kha#definstack Typedeliệu Typede// mản
E// vị
i}
Sau đâyTạo stac Ngăn xếngăn xếstack ta Void M{
S}
AAADDDTTT
ớn môn cấu
các phép toiên để giải liệu hợp lítrong stack
Đối tượn
1 Stack dù
ữ stack bằngà địa chỉ tưvào stack 1. Cấu trú
i báo cấu ne Max
def … El
def strung lưu ElementTtrí đỉ
int Top;} Stack;y là một sốck rỗng
ếp rỗng là ếp không đ để Top=-1MakeNul
S Top=
trúc dữ liệu
oán cơ bản thuật đó th
í để cài đặtk.
g cất giữ
ùng mảng
g một véc ương đối tthì T tăng
úc được mô
trúc stack…
lementTy
uct { nội dunType Eleỉnh ngăn; ; ố phép toá
ngăn xếp kđược phép c1; ll(Stack
=-1;
và giải thuậ
mà khônghành chươnt các phép
ữ
g
tơ lưu trữ trong mảnglên 1. Ngư
ô phỏng trê
k: // độ l
ype // ki
ng stackements[Mn xếp
án
không chứchỉ đến bất
k S)
Trang 7
ật Gi
g cần phải đng trình chtoán này. P
gồm n phầg). Khi đó ược lại, khên hình 2:
lớn
iểu dữ
k Max];
ứa bất kỳ mt kỳ vị trí n
áo viên hướ
định nghĩahạy được thPhần tiếp t
ần tử kế tiếstack rỗngi loại một p
một phần tửnào trong m
Hình 3: s
ớng dẫn : Ng
a lại hay giảhì ta phải ctheo nói về
ếp, T là địag khi T=-1, phần tử kh
ử nào, do đómảng kh
stack dùng mả
guyễn Đức N
ải thích thêchọn một cề các đối tư
a chỉ ở đỉnhkhi thêm m
hỏi stack th
ó đỉnh củahi khởi tạo
ảng
Nghĩa
êm. cấu ượng
h môt hì T
a
SSSTTTAAACCCKKK AAADDDTTT Trang 8
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
Kiểm tra stack rỗng Stack rỗng khi Top=-1 int IsEmpty(Stack S) {
Return (S Top==-1); } Kiểm tra stack đầy Stack đầy khi Top=Max-1 Int IsFull(Stack S) {
Return (S Top==Max-1); } Lấy nội dung phần tử tại đỉnh stack : Hàm trả về nội dung phần tử tại đỉnh của ngăn xếp khi ngăn xếp không rỗng. Nếu ngăn xếp rỗng thì hàm hiển thị câu thông báo lỗi. ElementType Top(Stack S) {
if (!IsEmpty(S)) return S.Elements[S.Top];
else printf("Loi! Ngan xep rong"); } Thêm một phần tử vào stack : Khi thêm phần tử có nội dung x (kiểu ElementType) vào ngăn xếp S (kiểu Stack), trước tiên ta phải kiểm tra xem ngăn xếp có còn chỗ trống để lưu trữ phần tử mới không. Nếu không còn chỗ trống (ngăn xếp đầy) thì báo lỗi; Ngược lại, dịch chuyển Top lên trên 1 vị trí và đặt x vào tại vị trí đỉnh mới. void Push(Stack S,ElementType X) {
if (IsFull (S)) printf("Loi! Ngan xep day!");
else {
S->Top=S->Top +1;
SSSTTTAAACCCKKK AAA
Bài tập lớ
}} Đẩy mộ Phần tử dịch chuvoid P{
i
e
} 1.3.2 M Nhiều kvới nhiềtình trạnkhác thìtượng trtrên ta lkích thưtrúc lưuTa thay khi toànkhác nh
• S
• H
AAADDDTTT
ớn môn cấu
S->E}
ột phần tử r
được xóa ruyển đỉnh củPop(Sta
if (!IsES->T
else prin
Mở rộng sta
khi ta cần tều stack, đng một stacì trống nhiràn cục bộlưu nhiều sước cố địnhu hai stack hai đầu củ
n bộ khônghiều so với Stack 1 đặt
o Khởio Đẩy mo Lấy m
Hai stack bị
trúc dữ liệu
Elements
ra khỏi stac
ra khỏi ngăủa ngăn xếpack S)
Empty(S)Top=S->T
ntf("Loi
ack dùng m
hao tác cùniều này có ck đầy tronều đây . Để xử lý stack vào mh nhưng độtrong 1 mảủa stack phg gian nhớ
trước, chỉ thuận chiề
i tạo stack bmột phần tmột phần tị tràn khi T
và giải thuậ
s[S->To
ck
ăn xếp là tạp xuống 1 v
)) Top-1;
i! Ngan
mảng.
ng một lúcthể dẫn đế
ng khi staclà hiện trường hợp
một mảng ộ lớn mỗi sảng. hát triển vềdã dùng hếchú ý: ều thao bằng cách tử vào stactử khỏi stacTop1>=Top
Trang 9
ật Gi
op]=X;
ại đỉnh của vị trí.
n xep ro
c ến ck
p
stack thì kh
ề hai phía nết. Các phé
tác giống tgán Top2=
ck thì Top2ck thì Top2p2
Hình 4:
áo viên hướ
ngăn xếp.
ong!");
hông xác đ
nên hiện tưép toán trê
trước, stac=Max 2 giảm đi 12 tăng lên
hai stack lưu
ớng dẫn : Ng
Do đó, khi
định. Sau đ
ượng tràn sên cách lư
k 2 ngược
1
u trữ trên cùng
guyễn Đức N
i xóa ta chỉ
đây là một
tack chỉ xẩtrữ này kh
chiều
g một mảng
Nghĩa
ỉ cần
cấu
ẩy ra hông
SSSTTTAAACCCKKK AAA
Bài tập lớ
Ta cũngtrong mchia đềustack phstack khdồn chúsang ph
2.2
Nếu nhưđiểm là stack củtràn stacpháp lưuỞ đây mngoài chnó còn ctheo trotrỏ về Nstack ở DSLK đđịnh mộthực hiệsau: struct tin trỏ tr typedeNX *To
AAADDDTTT
ớn môn cấu
g có thể có một mảng, ku ô nhớ chhát triển nhhác vẫn cònúng: có thểhải hoặc lùi
.1 Stack d
ư ở phần trđộ lớn củaủa ta bị dùnck nếu mảnu trữ stack
môi phần tửhứ thông tichứa địa ch
ong stack, nNULL. Về đây khá giđơn, chỉ khột phía là đện ở đầu củ
t Stack
rỏ đến
def struTop
trúc dữ liệu
nhiều hơnkhởi tạo bằo chúng. Nhanh bị trànn chỗ trống đẩy stack i chính nó
dùng DSLK
rước khi nga stack đượng thừa thãng không đ
k mới mà cử của stackin của chínhỉ của nút nút cuối cùmặt trực qiống với hác là ta cóđỉnh stack(pủa DSLK.
k {
nút tiế
uct Stac
và giải thuậ
n hai stack ằng cách Nếu một n mà các g thì ta sau nó sang trái.
K
ghiên cứu ợc khởi tạoãi (chỉ dùnđủ lớn! Phầó thể giải q
k được lưu nh tiếp
ùng quan
ó quy phía còn lạĐể tạo nên
Elem
strucếp theo};
ck NX;
Trang 10
ật Gi
về stack dùo từ đầu vàg một phầnần này xinquyết đượcvào một p
ại là đáy) n các nút ta
mentType
ct nganx
Hình 5: n
Hình 6: stack
áo viên hướ
ùng mảng à luôn cố đn nhỏ của m
n được giớic bất cập trphần tử nhớ
Các thaoa cần khai
e Info;
xep *Nex
/
hiều stack trê
k dùng DSLK
ớng dẫn : Ng
ta thấy rõ ịnh, điều đmảng), hoặi thiệu về mrên đó là dớ gọi là nú
o tác của sbáo một cấ
xt;
// ngăn
ên cùng một m
guyễn Đức N
một nhượcđó dễ dẫn tặc có thể b
một phươngdùng DSLKút. Các nút
tack đươc ấu trúc như
// thô
// con
xếp
mảng
Nghĩa
c ới
bị g
K. này
ư
ông
n
SSSTTTAAACCCKKK AAA
Bài tập lớ
ngăn xMột số Tạo stacKhởi tạVoid M{
*} Kiểm tStack int Is{
r} Lấy nộiTop trỏ Elemen{
i
e} Thêm mThêm mnếu cấphện cácNgược công thì
AAADDDTTT
ớn môn cấu
xếp phép toán
ck rỗng o bằng cácMakeNul
*Top=NUL
tra starỗng k
sEmpty(
return (
i dung phầnđến phần ntType
if (!IsEretu
else pri
một phần tửmột nút có p phát bộ nc thao tác c
lại nếu cì báo lỗi.
trúc dữ liệu
n
ch gán Topll(NX *T
LL;
ack rỗngkhi Top (NX Top)
(Top==NU
n tử tại đỉntử đỉnh staTop(NX
Empty(Tourn Topintf("Lo
ử vào stackthông tin
nhớ thành ccon trỏ nhưấp phát k
và giải thuậ
p bằng NULTop)
g trỏ vào
ULL);
nh stack : ack nên thôTop)
op)) p->Infooi! Ngan
k : X vào stac
công thì gáư hình vẽ 6
không thàn
Trang 11
ật Gi
//
LL
o NULL
ông tin ở đỉ
o; n xep r
ck bằng cáán thông ti6. nh
Hình 7: thê
áo viên hướ
con trỏ
ỉnh stack l
rong");
ách tạo ra n X cho dữ
êm một phần t
ớng dẫn : Ng
ỏ trỏ v
ấy qua Top
một nút Pữ liệu của
tử vào stack
guyễn Đức N
vào đỉnh
p
P kiểu cấu P; sau đó
Nghĩa
h
trúc, thực
SSSTTTAAACCCKKK AAA
Bài tập lớ
void P{
Npi{
}e
} Đẩy mộNếu ngăhiện đơnđến phầ void *{ ) xep ro } Nhận x
AAADDDTTT
ớn môn cấu
Push(NX
NX *p; p=(NX *)if(p!=NU{
p->Ip->n
} else
prin
ột phần tử răn xếp rỗnn giản bằnần tử tiếp th
*POP (N
if((*To
printf(ong!”);else { NX *
*Topfree
}
xét
trúc dữ liệu
X **Top,
)malloc(ULL)
Info=X; next=*to
ntf(“\nL
ra khỏi stacng thì báo lng cách lưuheo và cuố
NX **Top
op)==NUL
(“\nNgan
*p=*Top;p=(*Top)e(p);
và giải thuậ
,Element
(sizeof(
op;*top
Loi cap
ck ỗi, ngược l
u con trỏ Toối cùng là x
p)
LL
n
; )->next
Trang 12
ật Gi
tType X)
(NX));
p=p;
p phat b
lại việc xóop vào biếxóa P.
t;
Hình 8: x
áo viên hướ
)
bo nho!”
a phần tử đến trỏ P, sau
óa một phần t
ớng dẫn : Ng
”);
đầu của stau đó cho c
tử khỏi stack
guyễn Đức N
ack có thểon trỏ Top
Nghĩa
thực p trỏ
SSSTTTAAACCCKKK AAADDDTTT Trang 13
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
• Trong quá trình cài đặt tùy vào nhu cầu mà ta có thể dùng những thao tác nào của stack. Trong nhiều trường hợp ta có thể gộp hai thao tác lấy nội dung phần tử tại đỉnh stack và đẩy một phần tử ra khỏi stack thành một hàm duy nhất (sẽ nói đến trong phần cài đặt).
• Các phép toán trên chỉ là các phép toán cơ bản nhất. Ta có thể thiết kế ra nhiều phép toán khác tổng hợp từ các phép toán cơ bản này. Ví dụ khởi tạo stack từ một tập phần tử cho trước hay xóa toàn bộ một stack, hoặc có thể sao chép stack…
2.3 Các ứng dụng của Stack
Mặc dù cấu trúc stack rất đơn giản nhưng ứng dụng của stack là rất rộng: từ áp dụng để giải quyết các bài toán đơn giản như chuyển đổi cơ số đến các bài toán phức tạp hơn như tính toán một biểu thức toán học bất kì hay như một hệ thống các bài toán dùng stack khử các bài toán đệ quy để làm tối ưu trương trình. Stack có ứng dụng đặc biệt để tạo cơ chế hoạt động cho các trương trình dịch. Stack ứng dụng để nhúng một phần vào các trương trình lớn như hệ điều hành, trương trình ứng dụng …
2 Cài đặt (trên C)
2.1 Mô phỏng hoạt động của stack Đây là một trương trình đơn giản mô tả cấu trúc vào/ra của stack; chủ yếu để thấy rằng cấu trúc stack thì hoàn toàn đơn giản. Trưong trình gồm 4 thao tác:
1.push 2.pop 3.duyet 4.thoat Dùng DSLK để mô tả stack struct phantu { char hoten[25]; struct phantu *next; }; Trích dẫn cài đặt; file chạy trong thư mục Basic #include<stdio.h>
SSSTTTAAACCCKKK AAADDDTTT Trang 14
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
#include<conio.h> #include<string.h> #include<alloc.h> struct phantu { char hoten[25]; struct phantu *next; }; struct phantu *top; void push(char *); char *pop(); void duyet(); void main() { int c;char s[25]; clrscr(); top=NULL; do { printf("\n1.push 2.pop 3.duyet 4.thoat "); scanf("%d%*c",&c); if(c==1) { printf("\nHo ten ");gets(s);push(s); } if(c==2) { strcpy(s,pop()); if(strcmp(s,"")!=0) printf("\nPT lay ra: %s",s); else printf("\nDS rong"); } if(c==3) duyet(); } while(c!=4); }// End of Main //----------------------- void push(char *s)
SSSTTTAAACCCKKK AAADDDTTT Trang 15
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
{ struct phantu *p; p=(struct phantu *)malloc(sizeof(struct phantu)); strcpy(p->hoten,s); p->next=top; top=p; } //------------------------------- char *pop() { char s[25]=""; char *p; if(top==NULL) return ""; strcpy(s,top->hoten); top=top->next; p=(char *)s; return p; } //0------------------- void duyet() { struct phantu *p; if(top==NULL) printf("\nDS rong"); for (p=top;p!=NULL;p=p->next) printf("\n%s",p->hoten); }
2.2 Bài toán chuyển đổi giữa các cơ số
program BASE_N Source sode file: BASE_N.CPP Executed file: BASE_N.exe Chuyển đổi cơ số từ hệ thập phân sang hệ nhị phân (sử dụng stack lưu trữ dưới dạng mảng)
Chức năng của chương trình. • Chuyển đổi số thập phân sang số nhị phân 32 bit.
SSSTTTAAACCCKKK AAADDDTTT Trang 16
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
• Input: số thực bất kỳ có giá trị trong đoạn [2147483648.0 ; 2147483647.0],số nguyên đầu vào sẽ là cận dưới của số thực nhập vào.
• Output: một số nhị phân 32 bit Lưu đồ thuật giải.
Nhập số thập phân d. Bước này xác định đầu vào, đầu vào có thể là một số thực bất kỳ -2^16<=x<=2^16-1. Khi đó d=int (x) tức là lấy phần nguyên của x.
Khi d<0 thì biến cờ sign=1 để đánh dấu đầu vào là 1 số âm va gán d=-d.
Chuyển đổi thập phân sang nhị phân được thực hiện nhờ hàm int trans(long int, int *) (sẽ được nói kỹ trong phần sau)
Tính mã bù 2; được thực hiện bởi 2 việc: đảo bit và cộng thêm bit 1.
Có muốn làm lại : cho phép người dùng tiếp tục sử dụng chương trình mà khoongphiar khởi đọng lại nó.
Stack ADT sử dụng trong chương trình.
Stack trong chương trình được lưu trữ dưới dạng mảng.
Khai báo:const int bit_rate=32;
int stack[bit_rate]; int T=0;
Các thao tác cơ bản trên stack: - Push: đẩy một phần tử vào stack:
SSSTTTAAACCCKKK AAADDDTTT Trang 17
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
int push(int *stack,int *T,int x) { if(*T>bit_rate) {_error=2;return 0;} (*T)++; stack[*T]=x; return 0;
}
- Pop: lấy 1 phần tử ra khỏi stack.
int pop(int *stack,int *T) { if(*T<0) {_error=2;return 0;} (*T)--; return(stack[*T+1]);
}
Phân tích các hàm trong chương trình Hàm khởi tạo: - Khai báo: long int initial(int *bin) - Chức năng: nhập trả lại số thập phân cần chuyển đổi sang nhị phân. - Source code:
long int initial(int *bin) { double x=0.0; for(int i=0;i<bit_rate;i++) bin[i]=0; do{ if(x) {printf("\nDomain error!");getch();} intro(); printf("\nEnter 1 decimal number:"); scanf("%lf",&x); } while(!((x>=-2147483648.0)&&(x<=2147483647.0))); return((long int)x);
}
- Phân tích: đầu vào là một số thực bất kỳ. sau khi kiểm tra điều kiện
(((x>=-2147483648.0)&&(x<=2147483647.0))) thì hàm sẽ trả về phần nguyên của x là (long int) x. Nếu vi phạm điều kiện thì hàm sẽ đưa ra thông báo lỗi và yêu cầu nhập lại.
Hàm chuyển mã thập phân dương sang nhị phân. - Khai báo: int trans(long int x, int *bin) - Input: số thập phân. - Output: số nhị phân 32 bit.
SSSTTTAAACCCKKK AAADDDTTT Trang 18
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
- Source code: int trans(long int x, int *bin) { int stack[bit_rate]; int i=0,T=0; do{ push(stack,&T,x%2);i++; x=x/2; }while(x); i=0; while(T){ bin[bit_rate-T-1]=pop(stack,&T); } return 0;
}
- Phân tích: vòng lặp do{…}while. Là phần chính của hàm này. Nó thực hiện đưa(push) phần dư của phép chia x%2 vào stack. Vòng lặp thứ 2 sẽ lấy các phần tử trong stack và đưa vào mảng bin[] chính là mảng kết quả.
Hàm mã bù hai. - Khai báo: int two_complement(int *bin) - Input: số nhị phân. - Output: mã bù 2 của số nhị phân đầu vào. - Source code: int two_complement(int *bin) { int i,j,r=0; for(i=0;i<bit_rate;i++) bin[i]=~bin[i]; do{ if(bin[i]) {bin[i]=0;r=1;} else {bin[i]=1; r=0;} } while(r!=0); return 0;
}
- Hàm bao gồm 2 hàm con: Hàm đảo bit.
Khai báo: int NOT(int *bin) Input: số nhị phân. Output: mã bù 1 của số nhị phân. Source code:
SSSTTTAAACCCKKK AAADDDTTT Trang 19
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
int NOT(int *bin) { for(int i=0;i<bit_rate;i++) if(bin[i]) bin[i]=0; else bin[i]=1; return 0;
}
Hàm cộng thêm bit 1 vào 1 số nhị phân. Khai báo: int add_a_bit(int *bin) Input: số nhị phân. Output: số nhị phân đã cộng thêm 1. Source code:
int add_a_bit(int *bin) { int r=1,i=0; while(r){ if(bin[bit_rate-i-1]==0){ bin[bit_rate-i-1]=1; r=0; } i++; } return 0;
} Phân tích: biến int r; là biến lưu giá trị nhớ, vòng lặp
while kết thúc khi r=0. Nghĩa là số nhị phân đã được cộng thêm 1.
Phân tích đánh giá độ phức tập tính toán Ta có thể tính được độ phức tạp tính toán của các hàm (functions)
- Các hàm initial, pop, push, intro tốn thời gian là hằng số - Hàm trans trong tình huống tồi nhất là thược hiện bit_rate lần lệnh
push(stack,&T,x%2) +bit_rate lần gọi lệnh pop. - Hàm NOT thục hiện đúng bit_rate lần câu lệnh so sánh bin[i]=0. - Hàm add_a_bit. Trong tình huống tồi nhất là thực hiện bit_rate lần
câu lệnh so sánh r==0. Như vậy nếu bit_rate là hằng số thì thời gian tính của các hàm là hằng số.
Các ví dụ VD1: input: 1213
Output: Binary number:0000.0000.0000.0000.0000.0100.1011.1101
VD2: input:1.023
SSSTTTAAACCCKKK AAA
Bài tập lớ
2.3 Ps
2.3.1 C Xét một/… giả bao giờ trường hcác phép
1 (
Trong totrừ nên ngoặc ctrước sathì tính
• 1p
Ví dụ mmức ưu
• 5Thứ tự t
•
•
AAADDDTTT
ớn môn cấu
Polish Proang dạng
Cơ sở lý th
t biểu thứcsử chỉ xét cũng đặt g
hợp ta phảp toán. Ví
+2*3 1+2)*3 là h
oán học phở biểu thứ
có mức ưu au đó mới nlần lượt từ
-2+3-4+5 phải. (hình 9)
một biểu thứu tiên khác
+4*3-2/1^tính toán s 1^0=1
4*3=12
trúc dữ liệu
VD3: input
oblem :( bg hậu tố và
huyết
c toán học gcác toán tửgiữa các toải đặt thêm
dụ hai biểu
hoàn toàn k
hép nhân vức một 2*3
tiên cao nhnhân với 3ừ trái qua p
tính lần lư). ức chứa cánhau.
^0 (dạẽ là :
(5+4*3
(5+12-
và giải thuậ
Output: Binnumber:00
t: -1213 output: Binnumber:11
bài toán Bà tính biểu
gồm các toử mà thực hoán hạng (k
các cặp dấu thức
khác nhau
và phép chisẽ được tí
hất trong c3. Trong trưphải. Ví dụ
ượt từ trái q
ác toán tử c
ạng trung t
3-2/1)
-2/1)
Trang 20
ật Gi
nary 000.0000.000
ary 11.1111.111
Balan) chuu thức hậu
oán hạng: Ahiện phép kí pháp trunấu ngoặc đ
//. //
ia có mức ưính trước, sác phép toường hợp cụ biểu thức
qua
có
tố)
Hình 9:
áo viên hướ
00.0000.000
11.1111.111
uyển biểu u tố
A, B, 1, 2…toán với hng tố(Infixđể phân biệ
=7 =9
ưu tiên caosau đó mới
oán nên ta pcác phép toc :
tính biểu thứ
ớng dẫn : Ng
00.0000.000
11.1011.010
thức dạn
…và các toai toán hạn
x Notation)ệt thứ tự tín
o hơn phépi cộng thêmphải tính boán có cùn
c
guyễn Đức N
0.0001
0.0011
g trung tố
oán tử: +, -ng thì toán )). trong nhnh toán của
p cộng và pm 1. Cặp diểu thức (1
ng mức ưu
Nghĩa
ố
, *, tử
hiều a
phép dấu 1+2) tiên
SSSTTTAAACCCKKK AAADDDTTT Trang 21
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
• 2/1=2 (5+12-2) • 5+12=17 (17-2) • 17-2=15 15
Tuy nhiên trong một biểu thức thường không thể thiếu những dấu ngoặc với mục đích thu gọn biểu thức. Chẳng hạn ta có thể viết A*(B+C+D) hoặc A*B+A*C+A*D ; thì kết quả đều như nhau. Nhưng cách viết thứ nhất ngắn hơn và sẽ tính nhanh hơn ! Tuy nhiên một nhà toán học Balan J.Lukasiewicz đã phát hiện rằng dấu ngoặc cũng không cần thiết khi ta biểu diễn biểu thức số học theo kí pháp hậu tố (Postfix Notation) hoặc tiền tố (Prefix Notation). Chúng được gọi chung là kí pháp Balan (Polish Notation). 2.3.2 Biểu thức hậu tố và tiền tố Với kí pháp hậu tố, toán tử đặt sau các toán hạng. Ví dụ: Toán tử hai toán hạng
• A-B (trung tố) A B - (hậu tố) // phép trừ hai ngôi • A/B A B / • A^B A B ^ • A*B+C A B * C + • (B+C)*A B C + A * • A/B^(C+D) A B C D + ^ /
Toán tử một toán hạng • A! A ! • ~A A~ // quy ước ~ là phép trừ môt ngôi
Tổng hợp • (A!+B!)/C^D A ! B ! + C D ^ /
Với kí pháp tiền tố, toán tử đặt trước các toán hạng • A-B - A B • A*(B+C) * A + B C • A! ! A …v…v
Kí pháp hậu tố và tiền tố chỉ khác nhau về cách đặt các toán tử nên việc tính toán trên hai hang này tương tự nhau. Ta sẽ chỉ nghiên cứ về biểu thức hậu tố.
SSSTTTAAACCCKKK AAA
Bài tập lớ
2.3.3 T Xét mộtTa nhậntoán hạntử này đcác toán
• Nlư
• Nb(B
• Tcù
Nhận xé• C
blưsa
Tính giáhình 10Ta thấy toàn “mlên các 2.3.4 G Tất cả cmuốn tựcó rất nh
1. Mmtr
AAADDDTTT
ớn môn cấu
Tính giá tr
t biểu thứcn thấy khi dng trước đóđể tạo thànn tử tiếp thNếu ký tự đưu giá trị c
Nếu ký tự đbảo đã lưu tB+C).
Tính toán kùng được bét:
Các toán hạbảo lưu sauưu giữ các au. á trị biểu th. việc tính b
máy móc” vngôn ngữ
Giải thuật
các thành vự cài đặt bàhiều phiên
Một cài đặtmảng.Trươnrong thư m
trúc dữ liệu
rị biểu thứ
c hậu tố ở tduyệt biêu ó(B, C) sẽ
nh một toánheo (hình 9được đọc làcủa nó. đó là toán ttrước đó để
kết thúc khibảo lưu ch
ạng được đu được lôi r
kết quả tro
hức hậu tố
biểu thức hvà có thể càlâp trình.
viên trong nài toán mộ
n bản. Chúnt bằng CTDng trình tên
mục Balan1
và giải thuậ
ức hậu tố
trên: A B Cthức từ tráđược tác đ
n hạng mới). à toán hạng
tử(+) thì lôể tác động
i duyệt hếthính là kết q
đọc sau lại ra trước). Dong quá trì
: 2 3 4 + 5
hậu tố là hoài đặt được
nhóm đều t mình, nênng em xin DL kiểu n là Balan
Trang 22
ật Gi
C + A *ái qua phảiđộng bởi toi (B+C) ch
g(B, C) thì
ôi hai toán hvào chúng
t. Giá trị cuquả.
kết hợp vớDo đó ta ngình tính toá
6 - - *. Cá
oàn c
n giới thiệu
1.c Hình
áo viên hướ
// (i hễ gặp moán ho
ì ta
hạng g
uối
ới toán tử đghĩ tới mộtán. Giải thu
ác thao tác
hai trương
Hình
11: tính biểu
ớng dẫn : Ng
(B+C)*A ột toán tử
đọc trước (t CTDL kiểuật được m
được minh
g trình tiêu
h 10: tính biểu
thức hậu tố d
guyễn Đức N
(+) thì hai
(các toán hểu stack để
mô tả qua v
h họa trên
biểu:
u thức hậu tố
dùng stack
Nghĩa
hạng ể ví dụ
SSSTTTAAACCCKKK AAA
Bài tập lớ
2. M Cgg
Không ptheo giảProce// thủgán c// sử stack
1. Tt
2. R
3. U4. C5. R
AAADDDTTT
ớn môn cấu
Một cài đặtCả hai CTgiải thích cgồm:
o File no File
phụ thộc vải thuật saudure Caủ tục nho Valu
ử dụng mk rỗng Thêm dấuthúc Repeat
a. Đọc b. Nếu
i. c. Else
i.
ii. iii.
iv.
Until gặCall POP
Return
trúc dữ liệu
t bằng CTDTDL này đềchi tiết đư
nguồn + fword giải
vào cách càu: alculatenày tínhue một stac
u “)” và
ký tự XX là tocall P
e // nếuCall P
trong Call P
W = Z
W Call P
vào stặp dấu kP(S,T,Va
và giải thuậ
DL kiểu daều được được nêu ở
file chạy thích trươ
ài đặt như t
ePostfixh giá tr
ck S với
ào cuối
X trongoán hạnPUSH(S,T
u X là tPOP(S,T,
stack rPOP(S,T,
(X) Y;
PUSH(S,T
tack kết thúcalue);
Trang 23
ật Gi
anh sách liêđề cập ở pFile word
ơng trình vthế nào; tất
xExpressrị biểu
i T trỏ
biêu t
g P khi ng thì T,X);
toán tử,Y);
ra ,Z);
//
T,W); //
c “)”;
áo viên hướ
ên kết (Balphần 1, phd cùng thư
và hướngt cả các cá
sion(P,Vthức hậ
tới đỉn
thức P đ
duyệt t
thì và // lấ
// và
tác độn
đẩy gi
ớng dẫn : Ng
lan2). hần cài đặư mục. mỗ
g dẫn sử dch cài đặt
Value) ậu tố P
nh; khở
để làm d
từ trái
tác độấy hai t
à chứa vng X và
á trị t
guyễn Đức N
ặt cụ thể ỗi thư mục
dụng. đều phải tu
P, kết q
ởi tạo
dấu kết
qua phả
ng X vàtoán hạn
vào Y và
ào Y và
tính đượ
Nghĩa
và c
uân
quả
ải
ào. ng
à Z
Z
ợc
SSSTTTAAACCCKKK AAA
Bài tập lớ
Để có bchuyển nhiên) sthực hiệvào stac
2.3.5
Trong bdấu mở đóng ngngoặc lồtrước lạThêm nđến toándùng mvà lưu cVí dụ: c
Gọi Q lqua stac“(“ vào
• B• B• B• B• B• B• B• B• B• B
AAADDDTTT
ớn môn cấu
biểu thức htừ biểu thứ
sang hậu tốện cũng bằck.
5 Chuyểnhậu tốT
biêu thức trngoặc “(“
goăc “)” tưồng nhau tại ứng với dnữa khi gặpn hạng thứ
một stack đểcác toán tửchuyển biể
à biểu thứcck S. ThêmS. Thao tá
Bước 1: choBước 2 4:Bước 5: choBước 6: đẩyBước 7: choBước 8: loạBước 9 10Bước 11: 5 Bước 12: đẩBước 13: 6
trúc dữ liệu
ậu tố ta cầnức trung tốố thao tác nằng một giả
n đổi trungT
rung tố nếu thì phải xuương ứng. Dthì dấu mở dấu đóng np toán tử thứ hai rồi mớể lưu các dử để chờ toáểu thức tru
c trung tố, m dấu “)” vác minh họo “2” (toán: đẩy các do “3” vào Py “+” vào So “4” vào Pại “+” ra kh0: đẩy “–“ vào P ẩy “–“ vàovào P
và giải thuậ
n thao tác ố( dạng tự này được ải thuật dựa
g tố sang
u xuất hiênuất hiện dấDo các dấungoặc
ngoặc sau. hì phải duyới đặt toán
dấu mở ngoán hạng thứng tố: 2*((
ta cần chuvào Q để làọa trên hìnhn hạng) vàodấu ngoặc vP S P hỏi S và chvà ( vào S
o S
Trang 24
ật Gi
a
n ấu u
yệt n tử đó sau oặc (để chờứ hai tươn(3+4)-(5-6)
uyển Q sanàm dấu kết h 11: o P và toán tử v
ho nó vào PS
Hì
áo viên hướ
toán hạng ờ các dấu đg ứng. Ta
6)) sang dạ
g biểu thứcthúc và tư
vào S
P, sau đó lo
ình 12: chuyể
ớng dẫn : Ng
thứ hai. Dđóng ngoặcxét ví dụ ạng hậu tố.
c P dạng hương ứng là
oai “(“ khỏ
n biểu thức tr
guyễn Đức N
Do đó ta sẽc tương ứn
hậu tố thônà thêm dấu
ỏi S
rung tố sang h
Nghĩa
ng)
g u
hậu tố
SSSTTTAAACCCKKK AAADDDTTT Trang 25
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
• Bước 14: loại “–“ khỏi S và cho nó vào P, sau đó loại “(“ khỏi S • Bước 15: giống bước 14 • Bước 16: loại “*” khỏi S và cho nó vào P, sau đó loại “(“ khỏi S
2.3.6 Giải thuật Procedure Polish(Q,P)
1. Thêm “(“ vào cuối Q 2. Call PUSH(S,T,”(“);
Repeat
1. Đọc X từ Q khi duyệt từ trái qua phải 2. Case X
a. X là toán hạng: cho X vào P b. X là dấu mở ngoặc: call PUSH(S,T,”(“); c. X là toán tử:
i. while thứ tự ưu tiên của S[T] >= thứ tự ưu tiên của X
1. Call POP(S,T,W); 2. Cho W vào P
ii. Call PUSH(S,T,X); d. X là dấu đóng ngoăc:
i. Repeat 1. Call POP(S,T,W) ; 2. Cho W vào P
ii. Until gặp dấu “(“ iii. Loại “(“ khỏi S
Until stack S rỗng Return
Hai trương trình Balan1 và Balan2 và mỗi file word của nó hướng dẫn chi tiết cách cài đặt và các giải thuật sử lý xâu cho mỗi một trương trình.
2.3.7 Cài đặt thuật toán balan dùng DSLK ứng dụng stack Các phần
SSSTTTAAACCCKKK AAA
Bài tập lớ
1. 2. 3. 4. 5. 6. 7.
Phần nàkĩ ở trên 1. Phát
Đầu vàophần tử
• T
• T
AAADDDTTT
ớn môn cấu
PháSơ ChuChuTínCácVí
ày giải thícn
t biểu:
o: bài toánử: Toán hạng:
o Các ho Các b
Toán tử: (14o + - * o Phép
(cho phép
o ^ o !
thừa
trúc dữ liệu
át biểuđồ tín
uẩn hóauyển xânh biểuc phép dụ và
ch về cài đặ
n nhập vào
( 3 lọai) hằng số: PIbiến: X,Y,Z
Trnàtronhđưgiákhxo
4 loại) / trừ một ngphép ký hitrừ hai ng // //
và giải thuậ
u bài tnh toána xâu âu sangu thức xử lý độ phứặt còn giải
o một biểu
I=3.14…, EZ,I,J,K kiểrong biểu thào có ong BT hập vào sẽ ược nhập á trị sau
hi nhập ong cả BT.
gôi: - iệu giống ôi)
mũ giai
H
Trang 26
ật Gi
toán n
g dạng hậu tốlỗi
ức tạp thuật và c
thức(BT) t
E=2.71…,ểu thực. hức nhập c
Hình 13: sơ đồ
áo viên hướ
hậu tốố
của giấu trúc dữ
toán học dư
, và các hắn
có thể chứa
ồ tính toán biê
ớng dẫn : Ng
ố
iải thuliệu và giả
ưới dạng x
ng số thực
a 6 biến trê
êut thức balan
guyễn Đức N
uật ải thuật đã
xâu chứa cá
.
ên; nếu biế
Nghĩa
nói
ác
ến
SSSTTTAAACCCKKK AAADDDTTT Trang 27
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
o Sin, cos, tg, ln, sqr(căn bậc hai), abs (trị tuyệt đối), flo(lấy phần nguyên), rnd (hàm random)
Đầu ra: kết quả là một số thực tính toán được. 2. Sau đây là sơ đồ tính toán:
Nhập một sâu S độ dài tối đa 80 ký tự nếu sâu khác rống thì ta chuẩn hóa xâu, ngược lại thì nhập lại sâu. 3. Chuẩn hóa xâu gồm:
• Chuyển tất cả thành chữ hoa • Loại bỏ các dấu cách • Su ly toan tu '-' một ngôi,VD:(-1-2)->(0-1-2) (chèn số ‘0’ vào trước toán tử
một ngôi. • Sử lý thêm đóng ngoặc: người dùng không cần phải gõ các dấu đóng ngoắc
còn lại của biểu thức; trương trình sẽ đếm số mở ngoặc và tự điền số đóng ngoặc.
Hàm chuẩn hóa chỉ chuẩn hóa sơ qua, các phép sử lý lỗi được rải rác trong các hàm : chuyển hậu tố và tính biểu thức hậu tố.
Khai báo một cấu trúc:
struct nganxep { char xau[20]; // chứa một phần tử của biểu thức struct nganxep *next;// trỏ đến phần tử tiếp theo trong stack }; typedef struct nganxep NX; khai báo hai biến trỏ toàn cục kiểu NX NX *S=NULL,*P=NULL; // P được dùng để chứ biểu thức hậu tố dạng DSLK stack // S là stack khác làm thành phần chung chuyển giúp chuyển biểu thức dạng xâu P; và tính BT hậu tố P (S chứa giá trị cuối cùng) double X,Y,Z,I,J,K,giatri; // 6 biến & đáp số int isX=0,isY=0,isZ=0,isI=0,isJ=0,isK=0; 6 biến này xét xem các biến X,Y.. có mắt trong biểu thức nhập vào không ? Giả sử X có mặt thì isX=0 và ngược lại. 4. Chuyển biểu thức sang dạng hậu tố nhờ hàm : void hauto(char *bieuthuc) ;
SSSTTTAAACCCKKK AAA
Bài tập lớ
Hàm nà
void PUchar *Pkết quả int uutieint istoaint lentoint isnumint istoa Trích dẫ void P vùng n cho ph đẩy và //----
Hình 14
AAADDDTTT
ớn môn cấu
ày sử dụng
USH(NX *OP(NX **là xâu của
en(char *);antu(char);oantu(char)m(char *);anhang(cha
ẫn hai hàm
PUSH(NX *
nhớ cho p
hần tử mớ
ào stack --------
4: chuyển xâ
trúc dữ liệu
một số hà
*S,char *s*,char *); a đỉnh ; ); ar *);
m quan trọn
**top,cha { NX *p; p=(NX
phần tử p strcpy
ới này p->nex
} ---------
âu sang cấu
và giải thuậ
àm nhỏ khá
str); //l
//t //k // //k //kiểm
ng
ar *str)
*)malloc
p thêm vày(p->xau,
xt=*top;*
---------
u trúc stack
Trang 28
ật Gi
ác được liệ
//đẩy m/loại 1 phần
trả về số ưuký tự có ph/trả về độ d/kiểm tra mm tra có là
c(sizeof(ào str);
*top=p;
---------
kiểu DSLK
áo viên hướ
t kê trong
một nút có gn tử ở đỉnh
u tiên của ải là toán
dài toán tửmột xâu có
toán hạng
(NX)); /
/
/
---------
ớng dẫn : Ng
phần Phot
giá trị str vh stack, đồn
một toán ttử không ử VD: sin la
là số khôngg không
// cấp
// gán
// hai
---//
guyễn Đức N
otype ở co
vào stack Sng thời trả
tử
a 3 g? (double
phát độn
giá trị
thao tá
cơ chế
Nghĩa
ode.
S ả lại
e)
ng
ác
ế
SSSTTTAAACCCKKK AAADDDTTT Trang 29
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
hoạt động đã được nêu rõ trong file word chính char *POP(NX **top,char *str) {NX *p; if((*top)==NULL) return ""; // nếu stack chua có gì thì trả về sâu rỗng strcpy(str,(*top)->xau); // copy giá trị ở đỉnh vào con trỏ *str p=*top;*top=(*top)->next; // thực hiện thao tác loại phần tử đỉnh free(p); // giải phóng vùng nhớ return str; // trả lại giá trị của đỉnh }
Thao tác POP cho phép có hai cách để lấy giá trị ở đỉnh.
• Chú ý để phép toán thực hiện đúng đắn biến top đầu vào phải khai báo con trỏ của con trỏ
Trong hàm hauto ta mã hóa các toán tử và toán hạng như sau :
• Sin S • Cos C • Tg T • Ln L • Abs A • Rnd R • Flo F • Sqr Q • Pi P
Hàm tính độ dài toán tử sử dụng khi duyệt biểu thức nhập vào. Ví dụ khi ta nhập biểu thức : Sin ( cos ( tan( pi / 4 Sau khi chuẩn hóa thành :
1. SIN(COS(TG(PI /4))) Duyệt từ trái qua phải và mã hóa:
2. Vị trí 1gặp ‘S’ đoán là “SIN” tính độ dài toán tử này =3 lưu ‘S’ duyệt tiếp vị trí thứ 1+3=4; là ‘(‘
SSSTTTAAACCCKKK AAADDDTTT Trang 30
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
Chú ý ta có quan tâm đến nhập có đúng SIN hay không nên cần quan tâm đến ‘I’ và ‘N’. Chẳng hạn SIM báo lỗi
Sau khi chuyển hậu tố biểu thức trên thành dạng stack P như sau: NULLP4/TCS (dạng hậu tố) (***) Chú ý:
Quy định thứ tự ưu tiên của các phép toán(càng nhỏ càng có mức ưu tiên cao) • 0 : ( • 1 : + - • 2 : * / • 3 : S C T Q L R • 4 : ^ • 5 : ! • 6 : A F
Hàm kiểm tra là toán tử ? khi ký tự đó là một trong các giá trị : + - * / ^ ! S C T Q A L R F thì trả về 1 ; ngược lại trả về 0 Kiểm tra một sâu là số khi nó chỉ chứa các chữ số và có thể duy nhất một dấu ‘.’
Nhìn vào dạng hậu tố (***) ở trên mặc dù có dạng hậu tố nhưng bị ngược và ta không thể tính BT này bằng cách duyệt qua danh sách. Ta muốn duyệt từ P trong khi cấu trúc trên chỉ cho duyệt từ S !!!
Cần một hàm đảo stack P ở trên thành : P 4 / T C S NULL Trích dẫn : void DAO(NX **top) { NX *p,*q=NULL,*s; p=(*top)->next; (*top)->next=NULL; if(p!=NULL){ q=p->next;p->next=*top;} while(q!=NULL) { s=q;q=q->next; s->next=p;p=s; } if(p!=NULL)*top=p; }
SSSTTTAAACCCKKK AAADDDTTT Trang 31
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
Sau khi đã được một biểu thức hâu tố hoan chỉnh kiểu stack dùng DSLK ; trương trình sẽ kiểm tra có biến nào được nhập không. Nếu có thì đề nghị người dùng nhập các giá trị cho nó. 5. Viêc còn lại là tính biểu thức hậu tố và đưa kết quả ra màng hình : Thuật toán để tính đã được đề cập chi tiết trong file word chính ; ở đây ta chỉ giải thích một số điển lưu ý :
• Mỗi phần tử của stack là một cấu trúc có hai thành phần : « giá trị » là một xâu độ dài cố định 20 byte, và con trỏ next (2 byte) trỏ tới phần tử tiếp theo. Khi ta duyệt qua xâu biểu thức cần tính, với mỗi một phần tử nhận biết được chẳng hạn SIN thì ta lưu ‘S’ dưới dạng một xâu độ dài 20
cần một hàm nhỏ để chuyển đổi 1 ký tự char một xâu ! Đối với các số nhập vào chỉ cho phép số có đọ dài không quá 20. Các hằng số như PI và E thì được Turbo C++ 3.0 hỗ trợ.
• Vì biểu thức hậu tố (dạng DSLK stack) có chứa các biến X,Y,Z,I,J,K( các biến ở dạng xâu) nên ta cần một hàm chuyển để tính
char *chuyen(char *s) { if(strcmp(s,"X")==0) return gcvt(X,20,s); else if(strcmp(s,"Y")==0) return gcvt(Y,20,s); else if(strcmp(s,"Z")==0) return gcvt(Z,20,s); else if(strcmp(s,"I")==0) return gcvt(I,20,s); else if(strcmp(s,"J")==0) return gcvt(J,20,s); else if(strcmp(s,"K")==0) return gcvt(K,20,s); else return s; // là các số }
6. Một số thao tác sử lý lỗi được chèn vào trương trình : Trong hàm chuyển hâu tố như :
• Kiểm tra nhập có đúng không ? nếu không báo lỗi. o Nếu số nhập vào dài quá 20 Syntax error: Number is too long! o Nếu nhập sai SIM Syntax error: “SIM” It must be \"SIN\" or
\"SQR\"." …vv..
SSSTTTAAACCCKKK AAADDDTTT Trang 32
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
Trong hàm tính BT hậu tố
• Nếu chia cho 0 Errror: divide by zero! • Căn số âm Errror: Sqr(a negative number)! • Tính (-3)! Errror: Factorial(a negative number)!
7. Các ví dụ và độ phức tạp của giải thuật Cách nhập số liệu chỉ là một xâu biểu thức với các thành phần cho phép. Phần giao diện Dos nêu rõ cách nhập; nếu nhập sai báo lỗi. Độ phức tạp của thuật toán chỉ là O(n) Phần cài đặt bằng mảng không đưa ra ở đây, code và hướng dẫn được nêu rõ trong thư mục balan1.
2.4 Một số bài toán khử đệ quy (Derecursion ) Trước hết, ta nhắc lại khái niệm đệ qui. Ta nói một đối tượng là đệ qui nếu nó bao gồm chính nó như là một bộ phận hoặc nó được định nghĩa dưới dạng của chính nó. Khử đệ qui ở đây là biến một thủ tục đệ qui thành thủ tục chỉ chứa vòng lặp mà không làm ảnh hưởng gì đến các yếu tố khác chứ không phải là thay đổi thuật toán. Khi một thủ tục đệ qui được gọi từ chương trình chính, ta nói: thủ tục được thực hiện ở mức 1 (hay độ sâu 1 của tính đệ qui). Nhưng khi thực hiện ở mức 1 lại gặp lời gọi đến chính nó, nghĩa là phải đi sâu vào mức 2 và cứ như thế cho tới một mức k nào đấy. Rõ ràng mức k phải được hoàn thành xong thì mức (k-1) mới được thực hiện. Lúc đó ta nói: việc thực hiện được quay về mức (k-1) Khi từ một mức i, đi sâu vào mức (i+1) thì có thể có một số tham số, biến cục bộ hay địa chỉ (gọi là địa chỉ quay lui) ứng với mức i cần phải được bảo lưu để khi quay về tiếp tục sử dụng. Còn khi từ mức i quay về mức (i-1), các tham số, biến cục bộ và địa chỉ ứng với mức (i-1) phải được khôi phục để sử dụng. Như vậy, trong quá trình thực hiện, những tham số, biến cục bộ hay địa chỉ bảo lưu sau lại được khôi phục trước. Tính chất “vào sau ra trước” này dẫn tới việc sử dụng stack trong việc cài đặt các thủ tục khử đệ qui. Thực chất của việc khử đệ qui là chúng ta phải làm công việc của một trình biên dịch. Mỗi khi có lời gọi đến chính
SSSTTTAAACCCKKK AAADDDTTT Trang 33
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
nó thì stack sẽ được nạp để bảo lưu các giá trị cần thiết. Còn mỗi khi thoát ra khỏi một mức thì phần tử ở đỉnh stack sẽ được lấy ra để khôi phục lại các giá trị cần thiết cho mức tiếp theo. Ta có thể minh hoạ việc khử đệ qui bằng một ví dụ đơn giản sau: Bài toán duyệt cây. Giả sử có một cây nhị phân với các nút được định nghĩa như sau: struct { int data; node *left, *right;
} node; Xuất phát từ nút gốc, cần duyệt qua tất cả các nút của cây theo thứ tự trước (post order).Thủ tục đệ qui sẽ như sau: void postOrder (node* t) { if (t != NULL) { visit(t); postOrder(t->left); postOrder(t->right); } }
Ta có thể dễ dàng khử lời gọi đệ qui thứ 2 như sau: void postOrder (node *t) { LABEL_0: if(t==NULL) return; visit(t); postOrder(t->left); t= t->right; goto LABEL_0; }
Kỹ thuật trên gọi là khử đệ qui phần cuối. Để khử lần gọi đệ qui còn lại đòi hỏi phải tổ chức một ngăn xếp để lưu giữ các biến cục bộ, các tham số, và sử dụng các hàm thao tác trên ngăn xếp: push(t): đặt biến t vào đỉnh ngăn xếp pop: lấy 1 giá trị ở đỉnh ngăn xếp
SSSTTTAAACCCKKK AAADDDTTT Trang 34
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
isEmpty(): báo hiệu ngăn xếp đã rỗng Thủ tục viết lại như sau: void postOrder(node *t) { label LABEL_0, LABEL_1, LABEL_2; LABEL_0: if(t==NULL) goto LABEL_1; visit(t); push(t); t= t->left; goto LABEL_0; LABEL_2: t= t->right; goto LABEL_0; LABEL_1: if(isEmpty()) return; t= pop(); goto LABEL_2; }
Bây giờ, loại bỏ hoàn toàn các chỉ thị goto và tránh trường hợp nạp các nút rỗng vào stack ta có thủ tục duyệt cây không đệ quy chuẩn như sau: void postOrder (node *t) { push(t) do { t= pop(); if (t->left != NULL) push(t->left); if (t->right != NULL) push(t->right); } while(!isEmpty()); }
Sau đây là ví dụ minh hoạ cụ thể hơn cho kỹ thuật này, cài đặt sắp xếp nhanh (QuickSort) khử đệ quy: int stackLeft[100]; int stackRight[100]; int top= 0;
SSSTTTAAACCCKKK AAADDDTTT Trang 35
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
push (int left, int right) { top++; stackLeft[top]= left; stackRight[top]= right; } pop (int *left, int *right) { *left= stackLeft[top]; *right= stackRight[top]; top--; } int isEmpty() { return (top==0?1:0); } void quickSort (int *x, int n) { int left, right, i, j, temp, p; push(1, n); do { pop(&left, &right); i= left; j= right; p= x[(left+right)/2]; do { while(x[i]<p) i++; while(p<x[j]) j--; if(i<=j) { temp= a[i]; a[i]= a[j]: a[j]= temp; i++; j--; } while (i<=j); if(i<right) push(i, right); if(j>left) push(left, j);
SSSTTTAAACCCKKK AAADDDTTT Trang 36
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
while (isEmpty() != 0); }
2.5 Đóng gói stack bằng lớp(Class) trong C++ Phần này nêu cách biểu diễn stack bằng lớp gồm các thuộc tính và phương thức trên thuộc tính đó. Gồm hai ví dụ mô phỏng trong thư mục “stack in C++”. Một ví dụ dùng mảng (tên là Stack_Arr) và một ví dụ dung DSLK (tên là Stack_Lis). StackArr Trương trình gồm hai file: stackarr.h (header) và stackarr.cpp (application). File header khai báo cấu trúc lớp (để không “cồng kềnh”; trong file này viết luôn phần thực hiện (implementation). Ta khai báo một template: template <class stack_type, int max_size=10> class stack { public: // các phương thức stack(); // constructor bool push (const stack_type&); // đẩy một phần tử vào stack bool pop (stack_type&); // đẩy phần tử ở đỉnh ra khỏi stack bool get_top(stack_type&) const;// lấy phần tử ở đỉnh stack bool is_empty() const; //stack có rỗng không? bool is_full() const; //stack có đầy không? private://các thuộc tính int top; // chỉ số ở đỉnh stack stack_type items[max_size]; // mảng chứa các thành phần stack };
SSSTTTAAACCCKKK AAADDDTTT Trang 37
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
Stack_type là kiểu dữ liệu phần tử của stack , có thể là các kiểu dữ liệu cơ bản như : int, double hoặc các kiểu dữ liệu có cấu trúc như : struct, class. Ví dụ minh họa dùng kiểu int.
Max_size là kích thước tối đa của stack, ở đây chỉ cho là 10 để minh họa được phương thức is_full(). Phần code là hoàn toàn đơn giản vì chỉ minh họa thao tác của stack và cách cài đặt stack trên C++. Tuy nhiên nhóm thấy rằng các trương trình ở đây chưa cần thết phải dùng đến C++.
3 Ứng dụng
3.1 Phát bểu bài toán ứng dụng
Lập trình trương trình mô phỏng máy tính điện tử “CASIO fx 570” với giao diện đồ họa, thao tác chuột và bàn phím với các chức năng sau: (Trước khi làm trương trình này nhóm đã tìm hiểu khá kỹ về máy tính điện tử)
1. Tính toán biểu thức bất kì gồm các phép toán: (trong chế độ COMP)
1. + - * / (-) ^ ! 2. x , x , e , 10 , x 3. Sin, cos, tan, ln, log10, abs, rand, %, eng 4. nCr (tổ hợp), nPr (chỉnh hợp), Dx (đạo hàm), Sx (tích phân) 5. M+, M- : số nhớ tăng và giảm trong các phép cộng trừ
2. Tính toán trên miền phức: nhập và tính toán +, -, *, /(trong chế độ COMPLEX)
3. Chuyển đổi giữa các cơ số: DEC, HEX, BIN, OCT và tính toán trên đó (chế độ BASE-N)
4. Giải phương trình và hệ phương trình (chế độ EQN) (EQuatioN) 1. Phương trình bậc 2 và bậc 3 2. Hệ phương trình bậc 2 và bậc 3 3. Hệ phương trình tuyến tính bậc cao (có thể vài trục phương trình)
nhưng sẽ chuyển từ chế độ đồ họa văn bản để tính toán; tính song quay lại chế độ đồ họa.
5. Tính toán ma trận (chế độ MATRIX): chưa được bổ xung vì thấy các
SSSTTTAAACCCKKK AAADDDTTT Trang 38
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
phép tính gần giống giải hệ PT tuyến tính. 6. Một số khả năng tính toán
1. Cho phép lưu các phép tính đã tính và quay lại các phép tính đó (History).
2. Cho phép dùng nút DEL để sửa phép tính nhập sai. 3. Cho phép thiết lập các chế độ để tính toán:
1. FIX : làm tròn số và lấy bao nhiêu số sau dấu phẩy (0 9)
2. SCI :quy cách viết số theo lũy thừa của 10 đồng thời lấy bao nhiêu số sau dấu phẩy (0 9)
3. DEG :tính toán ở chế độ Decimal 4. RAD :tính toán ở chế đọ Radian 5. NORM :chuyển sang chế độ tính toán bình thường
(Normal) 4. Cho phép chuyển đổi giữa ba cách viết số: thập phân phân số
hỗn số. 5. Cho phép lưu các giá trị cần lưu vào các biến nhớ: A, B, C, D, E,
F, X, Y cũng như M. Có thể nhận biết là lưu số bình thường hay lưu dạng số phức.
6. Cho phép thực hiện các chức năng bộ nhớ: 1. Xóa toàn bộ bộ nhớ. và thiết lập các chế độ máy tính về
trạng thái ban đầu 2. Reset các chế độ máy tính về trạng thái ban đầu 3. Và cả hai thao tác trên
7. Khả năng nhận biết thông minh các phím được ấn và tác động khi ấn một phím bất kì và thể hiện sự thay đổi đó lên màn hình.(đặc biệt là các phím chức năng như: phím SHIFT, ALPHA, STO, MODE) và các phím có nhiều chức năng. (chú ý một phím có thể có nhiều chức năng khác nhau)
8. Các thao tác sử lý phím ANS (phím lưu giữ kêt quả phép tính gần nhất) là khá hay (giống như máy tính thật).
7. Các chức năng về đồ họa 1. Cho phép dùng cả chuột lẫn bàn phím 2. Giao diện thân thiện và đẹp:
SSSTTTAAACCCKKK AAADDDTTT Trang 39
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
1. Các nút phím thiết kế nổi 2. Có 9 giao diện để lựa chọn 3. Các công cụ được thiết kế trượt chứa các Menu và các
Radio Button 4. … và còn nhiều …được nói rõ hơn trong file word hướng
dẫn ở thư mục Calculator.
Giao diện trương trình (chú ý nên dùng PC để chạy trương trình này vì các laptop thường không hiện đầy đủ chữ đồ họa)
Hình 14: giao diện trương trình chính
3.2 Mô tả, đánh giá độ phức tạp của giải thuật
SSSTTTAAACCCKKK AAADDDTTT Trang 40
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
Vì bài trương trình này chứa nhiều bài toán con khác nhau nên ta xem xét độ phức tạp của từng bài toán: ví dụ: Độ phức tạp của phần tính toán biểu thức là độ phức tạp của bài toán Balan (đã xét ở trên) O(n), với n là độ dài của xâu nhập vào. Các thao tác: cộng ma trận là O(n); nhân ma trận là O( ) Độ phức tạp của bài toán giải phương trình tuyến tính là O( ) vì: ở đây dùng phương pháp tính DET với thời gian tính O( ).
Ta chỉ có thể đánh giá được thời gian tính của từng giải thuật trong trương trình mà không có thời gian tính cho cả trương trình này.
3.3 Mô tả cài đặt trương trình Bài toán được chia ra từng phần nhỏ :
• Xử lý giao diện : Hiến (trưởng nhóm) làm • Tính toán biểu thức trong chế độ COMP(chế độ thường) : Tùng làm • Tính toán biểu thức trong chế độ COMPLEX : Minh làm • Giải các loại phương trình và hệ PT: Phương làm • Chế độ BASE-N: Thanh Tùng làm • Tổng hợp lại : trưởng nhóm kết hợp với tất cả thành viên hợp tác
Một số vấn đề mới được đặt ra
• Sử lý chuột kết hợp bàn phím và tương tác giữa các bộ phận • Thao tác với các phím, mỗi phím có nhiều chức năng và có ảnh hưởng lẫn
nhau khi ta gõ 1 phím bất kì( trạng thái làm việc phải được đưa lên màn hình trạng thái)
• Vấn đề tính toán số phức và số thực phải sử lý xâu rất nhiều • Vấn đề giải PT bậc 3 hệ PT tuyến tính và tính toán ma trận • Vấn đề làm tròn số(FIX,SCI) và chuyển đổi một số thực phân số hay hỗn
số • Vấn đề thao tác với các biến nhớ. • Vấn đề liên kết các trương trình nhỏ thành trương trình lớn • ……
SSSTTTAAACCCKKK AAADDDTTT Trang 41
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
Giải quyết vấn đề (theo phương pháp chí để trị!) • Trước tiên phải vẽ được giao diện rõ ràng • Quy định xác định các tọa độ và quy định các phím PC tương ứng với các
phím Calculator và dùng các ngắt chuột để thực hiên các thao tác Click • Mỗi phím sẽ là một hàm riêng • Xây dựng từng module nhỏ, cho chạy độc lập và kiểm tra đúng đắn trước
khi gép vào trương trình lớn • Vấn đề tổng hợp sẽ dễ dàng nếu có những quy định chung được thống nhất
như: biến, hàm: đầu vào, đầu ra; đặc biệt cần trao đổi thường xuyên • Khi đã tổng hợp xong tất cả cùng chạy thử và tìm những lỗi khó phát hiện.
(việc gỡ lỗi được tiến hành liên tục trong suốt quá trình làm, và là một quá trình tinh chỉnh dần dần).
• …. Mặc dù bài tập này viết về stack nhưng phần lớn code là về các phần sử lý khác. Tuy nhiên bản chất stack chỉ là một cơ cấu rất đơn giản, chính vì đơn giản nên ta khó thấy được ứng dụng thực tế của nó. Là cơ cấu đơn giản nên stack thường đóng vai trò trung gian trong các giải thuật mà điển hình là cơ cấu cho các bài toán đệ quy; nhở đó ta có thể dùng phương pháp khử đệ quy để tối ưu hóa trương trình về mặt tốc độ. (các trương trình dịch dùng stack chứa các kết quả trong đệ quy thì khi ta muốn khử đệ quy thì lại dùng stack). Bản chất nó là ngược nhau. Sau đây là một số ví dụ để kiểm thử trương trình: (quan trọng)
3.4 Ví dụ minh họa và hướng dẫn sử dụng Chạy trương trình CALC.C (cần có file EGAVGA.BGI) Vào giao diện Graphics, click phím ON để chạy. Các phím phím ẩn(chữ nhở phía trên) phải dùng phím SHIFT hoặc ALPHA cùng mới có hiệu lực. vd SHIFT và SIN tương đương ARCSIN Chú ý: màu vàng tượng trưng cho shiftl màu đỏ tượng trưng cho alpha VD1: + - * / Phía trên màn hình tính toán có 3 chữ: COMP DEC NORM tượng trương cho chế
SSSTTTAAACCCKKK AAADDDTTT Trang 42
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
độ hiện hành COMP(computing) DEC(decimal) NORM (normal) Dùng chuột hoặc bàn phím gõ:
• 10 / 3 Enter với phím
• 10 ÷ 3= với chuột (‘÷’ lấy trong bảng mã mở rộng ASCII)
Kết quả ra 3.3333… Gõ tiếp
• - 3 =
Kết quả ra 0.3333.. (chú ý dòng chữ ANS tượng trưng cho kết quả phép tính trước) Gõ phím S<->D cho ra kết quả 1/3, gõ lần nữa cho kết quả 0.3333.. Gõ 2 phím
• SHIFT và S<->D
Cho kết quả là hỗn số(nếu là phân số >1) Phía trên màn hình tính toán bây giờ có thêm một mũi tên nhỏ báo hiệu trong bộ nhớ máy tính đã lưu lại phép tính trước đó. Click vào nút gần chữ History để xem.(cấu trúc lưu trữ cho history là DSLK kép). Nếu đã có những phép tính được tính trong quá khứ ta có thể xem lại bằng phím mũi tên phía phải dưới, sau đó có thể quay lại Phím ON có thể xóa History Sau mỗi VD gõ AC để bắt đầu tính VD2: căn và lưu biến nhớ Gõ 3 phím: (tính căn bậc 2)
• √ 9 =
ra 3 Gõ 4 phím (tính căn bậc n)
• 4 √ 16 =
ra 2 Gõ 3 phím
• SHIFT RLC/STO A ( A tượng trưng cho phím có chữ A màu đỏ)
giá trị 2 đã được gán cho biến A Gõ phím AC sau đó gõ 2 phím
• CLR A
hiển thị giá trị vừa lưu và ta có thể tính toán với giá trị A bằng cách gõ 2 phím: • ALPHA A
VD: gõ ALPHA A + 3 - ALPHA A
SSSTTTAAACCCKKK AAADDDTTT Trang 43
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
đáp số là 3. Tương tự cho các biến nhớ khác. Giá trị các biến này giữ nguyên cho đến khi xóa nó(CLEAR) hoặc thay bằng giá trị khác. VD3: SIN COS TAN …LN ABS … Gõ 6 phím
• Sin ( PI ÷ 2 =
ra 1 Gõ 4 phím
• SHIFT SIN 1 =
ra PI/2 Gõ 6 phím
• Ln ( e ^ 2 =
ra 2 Các hàm khác tương tự… VD4: phép cộng gộp M+ Gõ 6 phím
• 1 M+ 2 M+ 3 M+
tổng của 3 số đã được lưu vào biến M Tương tự 2 phím
• SHIFT M+ thành M-
VD5: chuyển sang chế độ phức Chý ý: phí trên dòng chữ COMP CMPLX Nhấn MODE và chọn COMPLEX Gõ các phím
• ( 1 + i ) * ( 1 - i )
Kết quả 2 Chú ý : chế độ phức chỉ hỗ trợ 4 phép tính cơ bản và phép trừ 1 ngôi VD6 : chuyể sang chế độ giải hệ phương trình Nhấn MODE và chọn EQN Chọn một trong 5 chế độ
Phương trình bậc 2 PT bậc 3
Hệ phương trình bậc 2
SSSTTTAAACCCKKK AAADDDTTT Trang 44
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
HPT bậc 3 Hệ phương trình tuyến tính bậc cao
Vd Chọn 4 để giải PT bậc 3 Nhập theo hướng dẫn để giải PT bậc 3 bất kì Vd : a=1 b=-6 c=11 d=-6
x1=1 x2= 3 x3= 2 VD6: các chế độ hiển thị giá trị FIX SCI Nhấn
• SHIFT MODE
Sau đó chọn một trong 5 lựa chọn 1. NORM - chế độ thường
2. DEG - chế độ decimal
3. RAD - chế độ radian
4. FIX - chế độ định dạng số chữ số sau dấu phẩy
5. SCI - chế độ viết quy cách theo lũy thừa của 10
VD7 : xóa bộ nhớ Nhấn 2 phím
• SHIFT 9
Chọn 3 chế độ Memory Setup All Trong đó Memory là xóa bộ nhớ vd các biến A,B,C…cho cả số phức lẫn số thực Setup là xóa các chế độ thiết lập vd FIX,SCI, MODE… ALL là xóa toàn bộ, đưa máy về trạng thái ban đầu VD8: phím DEL Gõ như sau
• (2+4)+(4+2
Sau đó gõ phím DEL 5 lần; sau đó gõ tiếp • -(4+2=
ra 0 Vd nữa Gõ
• 2 / Tan ( pi / 2
Sau đó gõ phím DEL 5 lần; sau đó gõ tiếp
SSSTTTAAACCCKKK AAADDDTTT Trang 45
Bài tập lớn môn cấu trúc dữ liệu và giải thuật Giáo viên hướng dẫn : Nguyễn Đức Nghĩa
• Sin ( pi / 2
ra 2 VD9: một số tiện ích Click vào phím nhỏ gần chữ Options và chọn các giao diện Kéo chuột ra phía lề trái có một menu popup hiện lên, chọn add CLOCK để xem ngày giờ hệ thống. có thể tắt đồng hồ đi bằng cách làm lại. VD10: tắt máy và thoát khỏi trương trình Tắt máy: SHIFT AC Sau khi khởi động lại bằng ON thì bộ nhớ lúc trước khi tắt không bị mất. Thoát: click vào dấu nhân phía trên trái Tất cả các ví dụ ở trên là rất đơn giản 4 Kết luận Sau khi bốc thăm chủ đề một cách công bằng và trung thực, nhiều bạn cho rằng chúng em gặp may và rằng Stack ADT là một chủ đề quá dễ(quả thật cũng may !). Mới đầu chúng em cũng chỉ biết Stacks là một cấu trúc theo kiểu LIFO (Last – In – First – Out); còn về mặt ứng dụng thì chỉ biết cài đặt một số trương trình đơn giản theo kiểu mô phỏng hoạt động của Stacks…(chỉ đến vài trục dòng code). Với quyết tâm xây dựng được những trương trình lớn hoàn chỉnh có ứng dụng Stacks cùng với quá trình tìm tòi sách vở, chúng em nhận ra “Stacks quả thật là kì diệu”.