baocao

56
Mục lục Mục lục.........................................................1 I.Giới thiệu về đề tài:.........................................2 Các phương pháp biểu diễn phép toán hai ngôi:.................2 Cây biểu diễn biểu thức.......................................2 Thế nào là ký pháp nghịch đảo Ba Lan?.........................4 II.Cấu trúc dữ liệu:............................................5 III. Thuật toán cơ bản:.........................................5 IV. Mở rộng đề tài:.............................................8 VI. Kết quả chương trình:......................................40 VII. Kết luận:.................................................41 VIII. Nhận xét của giáo viên hướng dẫn:........................42

Transcript of baocao

Page 1: baocao

Mục lục

Mục lục.............................................................................................................................................1I.Giới thiệu về đề tài:........................................................................................................................2

Các phương pháp biểu diễn phép toán hai ngôi:..........................................................................2Cây biểu diễn biểu thức................................................................................................................2Thế nào là ký pháp nghịch đảo Ba Lan?......................................................................................4

II.Cấu trúc dữ liệu:...........................................................................................................................5III. Thuật toán cơ bản:......................................................................................................................5IV. Mở rộng đề tài:...........................................................................................................................8VI. Kết quả chương trình:...............................................................................................................40VII. Kết luận:..................................................................................................................................41VIII. Nhận xét của giáo viên hướng dẫn:.......................................................................................42

Page 2: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

I.Giới thiệu về đề tài:”KÝ PHÁP NGHỊCH ĐẢO BA LAN PHƯƠNG PHÁP TÍNH GIÁ TRỊ BIỂU THỨC TOÁN HỌC”  Khi lập trình, tính giá trị một biểu thức toán học là điều bình thường. Tuy nhiên, trong nhiều ứng dụng (như chương trình vẽ đồ thị hàm số chẳng hạn, trong đó chương trình cho phép người dùng nhập vào hàm số), ta cần phải tính giá trị của một biểu thức được nhập vào từ bàn phím dưới dạng một chuỗi. Với các biểu thức toán học đơn giản (như a+b) thì bạn có thể tự làm bằng các phương pháp tách chuỗi “thủ công”. Nhưng để “giải quyết” các biểu thức có dấu ngoặc, ví dụ như (a+b)*c + (d+e)*f ,  thì các phương pháp tách chuỗi đơn giản đều không khả thi. Trong tình huống này, ta phải dùng đến Ký Pháp Nghịch Đảo Ba Lan (Reserve Polish Notation – RPN), một thuật toán “kinh điển” trong lĩnh vực trình biên dịch.

 Để đơn giản cho việc minh họa, ta giả định rằng chuỗi biểu thức mà ta nhận được từ bàn phím chỉ bao gồm: các dấu mở ngoặc/đóng ngoặc; 4 toán tử cộng, trừ, nhân và chia (+, -, *, /); các toán hạng đều chỉ là các con số nguyên từ 0 đến 9; không có bất kỳ khoảng trắng nào giữa các ký tự.

Các phương pháp biểu diễn phép toán hai ngôi:

Một phép toán hai ngôi trên tập hợp X là một ánh xạ f: X×X →X cho (a,b) f(a,b)A. Ánh xạ f khi đó thường được ký hiệu bởi *, được gọi là toán tử, các phần tử a, b

được gọi là các hạng tử (còn gọi là toán hạng).

Khi viết biểu thức biểu diễn phép toán đó ta có thể đặt ký hiệu toán tử ở trước, sau hoặc giữa các toán hạng (là biến hoặc hằng). Thông thường trong các biểu thức đại và số học, ta viết kí hiệu phép toán giữa hai hạng tử( trung tố). Ví dụ : a +b, a * b, ... Khi một biểu thức có nhiều phép toán, ta dùng các cặp dấu ngoặc "(", ")" và thứ tự ưu tiên các phép toán để chỉ rõ thứ tự thực hiện các phép toán. (Các phép toán đều quy về phép toán 2 ngôi.)

Ta cũng có thể viết hai hạng tử trước và kí hiệu toán tử sau (hậu tố). Chẳng hạn:

a + b viết là a b +, a*b viết là a b *

Cũng có thể viết toán tử trước, hai toán hạng sau( tiền tố). Chẳng hạn:

a + b viết là + a b, a * b viết là * a b

Cây biểu diễn biểu thứcDùng cây biểu diễn biểu thức có thể thấy rõ trình tự tính toán biểu thức.

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 2 Lớp 06T4

Page 3: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

Ví dụ: a*(b+c)-d^5Được thực hiện theo sơ đồ biểu diễn bởi cây nhị phân sau:

- / \ * ^ / \ / \ a + d 5 / \ b c

Ta mô tả quá trình đọc, ghi nhận giá trị và thực hiện phép tính, giống như quá trình duyệt cây biểu thức theo thứ tự giữa như sau:

1. Đọc và ghi nhận giá trị biến a(con trái)2. Đọc và ghi nhận loại phép toán * (con trái)3. Đọc giá trị biến b (con trái)4. Đọc và ghi nhận loại phép toán + (con phải)5. Đọc giá trị biến c (con phải) thực hiện phép cộng b+c=x và ghi nhận kết quả x,thực

hiện phép nhân a*x = y và ghi nhận kết quả y6. Đọc và ghi nhận phép toán -7. Đọc giá trị biến d8. Đọc và ghi nhận phép toán ^9. Đọc giá trị 5 và thực hiện phép lũy thừa z=d^5, thực hiện phép trừ k=y-z

Để đơn giản ta giả sử các phép toán đều là hai ngôi. Khi đó cây biểu thức là cây nhị phân đầy đủ. Quy tắc thực hiện phép toán trên cây như sau:

Hoặc duyệt cây theo thứ tự giữa mỗi lần duyệt con phải nếu đã tính được giá trị tại con đó thì thực hiện phép tính quy định bởi toán tử ghi tại đỉnh cha.

Viết tuần tự các đỉnh duyệt theo thứ tự giữa thì ta có dãy

- - / \ / \ * ^ + ^ / \ / \ / \ / \ a + d 5 * c d 5 / \ / \ b c a b

a * b + c - d ^ 5 (1)

Theo cách này, mỗi khi duyệt một đỉnh

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 3 Lớp 06T4

Page 4: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

1. Nếu là lá bên trái (biến hoặc hằng) thì ghi nhận giá trị của biến2. Nếu là toán tử thì lưu dạng của toán tử3. Nếu là con phải và lá thực hiện phép tính theo toán tử đã lưu ở đỉnh cha giữa các

giá trị đã lưu tại con phải và giá trị mới đọc tại con trái, ghi kết quả vào đỉnh cha.

Hoặc duyệt cây biểu thức trên theo thứ tự sau: Mỗi đỉnh được duyệt sau khi cả hai đỉnh con đã được duyệt. Khi đó mỗi khi duyệt một đỉnh trong ta thực hiện toán tử ghi tại đỉnh này với giá trị của hai con của đỉnh ấy.

Thứ tự duyệt các đỉnh khi đó sẽ là: a b c + * d 5 ^ - (2)

Khi duyệt theo thứ tự sau, việc thực hiện phép tính tiến hành theo quy tắc:

Mỗi khi thăm một đỉnh thì:

1. Nếu là lá thì ghi nhận giá trị của biến2. Nếu là đỉnh trong thì thực hiện toán tử ghi ở đỉnh này vào các giá trị ghi ở hai đỉnh

con, ghi kết quả vào chính đỉnh này.

Với dãy (1) nếu không dùng đến dấu ngoặc, có thể có hai cây biểu thức khác nhau cho cùng một dãy đỉnh khi duyệt thứ tự giữa. Còn với dãy (2) cùng với lưu ý rằng các biến và hằng luôn được biểu diễn bằng các lá, các toán tử luôn biểu diễn bởi các nút trong, từ mỗi dãy dạng (2) ta luôn dựng lại được cây biểu thức duy nhất theo giải thuật sau: Khi độ dài dãy lớn hơn 1, duyệt từ bên trái sang, nếu gặp một phần tử là toán tử, thì lấy hai phần tử đứng trước nó ra khỏi dãy chuyển thành hai con của phần tử ấy (theo đúng thứ tự). Vì thế biểu thức viết bởi dãy (2) là hoàn toàn xác định.

 Thế nào là ký pháp nghịch đảo Ba Lan?  Cách trình bày biểu thức theo cách thông thường tuy tự nhiên với con người

nhưng lại khá “khó chịu” đối với máy tính vì nó không thể hiện một cách tường minh quá trình tính toán để đưa ra giá trị của biểu thức. Để đơn giản hóa quá trình tính toán này, ta phải biến đổi lại biểu thức thông thường về dạng hậu tố - postfix (cách gọi ngắn của thuật ngữ ký pháp nghịch đảo Ba Lan). Để phân biệt hai dạng biểu diễn biểu thức, ta gọi cách biểu diễn biểu thức theo cách thông thường là trung tố - infix (vì toán tử nằm ở giữa hai toán hạng).   Ký pháp nghịch đảo Ba Lan được phát minh vào khoảng giữa thập kỷ 1950 bởi Charles Hamblin - một triết học gia và khoa học gia máy tính người Úc - dựa theo công trình về ký pháp Ba Lan của nhà Toán học người Ba Lan Jan Łukasiewicz. Hamblin trình bày nghiên cứu của mình tại một hội nghị khoa học vào tháng 6 năm 1957 và chính thức công bố vào năm 1962.

Từ cái tên hậu tố các bạn cũng đoán ra phần nào là theo cách biểu diễn này, các toán tử sẽ được đặt sau các toán hạng. Cụ thể là biểu thức trung tố: 4+5 sẽ được biểu diễn lại thành 4 5 +.

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 4 Lớp 06T4

Page 5: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

II.Cấu trúc dữ liệu:Ta xây dựng kiểu cấu trúc toantu theo kiểu stack (ngăn xếp) gồm các trường:+ Trường tt kiểu char để chứa các toán tử và hàm.+ Trường next kiểu con trỏ cấu trúc toantu chỉ đến phần tử kế tiếp.

struct toantu{

char tt;toantu *next;

} ;Kiểu cấu trúc thứ hai là hauto theo kiểu danh sách liên kết đơn gồm:+ Trường letter kiểu mảng kí tự để chứa các kí hiệu của toán hạng, toán tử ,

hàm.+ Trường value kiểu double để chứa giá trị thực của các toán hạng.+ Trường next kiểu con trỏ cấu trúc hauto để chỉ đến phần tử kế tiếp.

struct hauto{

char letter[10];double value;hauto *next;

};typedef toantu *stack;typedef hauto *list;stack S;list P;

III. Thuật toán cơ bản:Chuyển đổi từ trung tố sang hậu tố

  Thuật toán chuyển đổi này được phát minh bởi vị giáo sư người Đức nổi tiếng Edsger Dijkstra (cũng là tác giả của thuật toán tìm đường đi ngắn nhất được đặt theo tên ông và semaphore, một kỹ thuật để đồng bộ các tiến trình trong lập trình đa nhiệm). Thuật toán này cũng dựa theo cơ chế ngăn xếp. Ý tưởng chung của thuật toán cũng là duyệt biểu thức từ trái sang phải:

-          Nếu gặp một toán hạng (con số ) thì ghi nó vào chuỗi kết quả (chuỗi kết quả là biểu thức trung tố).

-          Nếu gặp dấu mở ngoặc, đưa nó vào stack. -          Nếu gặp một toán tử (gọi là o1 ), thực hiện hai bước sau:

* Chừng nào còn có một toán tử o2 ở đỉnh ngăn xếp. Và độ ưu tiên của o1 nhỏ hơn hay bằng độ ưu tiên của o2 thì lấy o2 ra khỏi ngăn xếp và ghi vào kết quả.

* Push o1 vào ngăn xếp -          Nếu gặp dấu đóng ngoặc thì cứ lấy các toán tử trong ngăn xếp ra và ghi vào

kết quả cho đến khi lấy được dấu mở ngoặc ra khỏi ngăn xếp.

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 5 Lớp 06T4

Page 6: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

-          Khi đã duyệt hết biểu thức trung tố, lần lượt lấy tất cả toán tử (nếu có) từ ngăn xếp ra và ghi vào chuỗi kết quả.

 Để dễ hiểu, bạn hãy quan sát quá trình thực thi của thuật toán qua một ví dụ cụ thể sau:  Biểu thức cần chuyển đổi: 3+4*2/(1-5)

Kí tự Thao tác Stack Chuỗi hậu tố3 Ghi 3 vào hậu tố 3+ Push + vào stack + 34 Ghi 4 vào hậu tố + 3 4* Push * vào stack + * 3 42 Ghi 2 vào hậu tố + * 3 4 2/ Lấy * ra khỏi stack, ghi vào

kết quả, và push / vào stack+ / 3 4 2 *

( Push ( vào stack + / ( 3 4 2 *1 Ghi 1 vào hậu tố + / ( 3 4 2 * 1- Push – vào stack + / ( - 3 4 2 * 15 Ghi 5 vào hậu tố + / ( - 3 4 2 * 1 5) Pop cho đến khi lấy được ( ,

ghi các toán tử pop được ra hậu tố

+ / 3 4 2 * 1 5 -

Pop tất cá các toán tử ra khỏi ngăn xếp và ghi vào hậu tố.

3 4 2 * 1 6 - / +

* Hàm khởi tạo cho stack S và list P:void create();

* Hàm kiểm tra stack rỗng:int empty();

* Hàm đẩy các toán tử vào stack S:void push(char x)

* Hàm lấy ra một phần tử trên đỉnh stack đồng thời xoá phần tử đó ra khỏi stack:

char pop();* Hàm xem phần tử trên đỉnh stack nhưng không xoá phần tử đó:

char top();* Hàm chèn một phần tử vào cuối danh sách list P:

void insert_last(char *x,double val);* Hàm kiểm tra độ ưu tiên của các toán tử:

int ref(char x){ if ( ( x == '+')|| ( x =='-')) return 1;

else if ( ( x == '*')|| ( x== '/')) return 2; else if (x=='(' || x==')' ) return 0

else return -1;}

* Hàm kiểm soát các kí tự nhập vàoint test(char x)

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 6 Lớp 06T4

Page 7: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

{ if ((x>='0')&&(x<='9')) return 1;else if(x== '+' ||x=='-'||x=='*'||x=='/')return 2;else if ( x=='(' || x==')'|| x==' ' )return 4;

else return 0; }

* Hàm chuyển biểu thức trung tố sang hậu tố:void convert(char *expr){ char temp[10]; int n,l,i; create(); n=strlen(expr); i=0; while(i<n) { while(expr[i]==' '&&i<n) i++; if(expr[i]=='(') push(expr[i]); else if(expr[i]==')') { while(top()!='(')

{ temp[0]=pop();

temp[1]=’\0’;insert_last(temp,1);

} pop();

} else if(test(expr[i])==1)

{ l=0;

temp[l]=expr[i]; l++; temp[l]='\0';

insert_last(temp,expr[i]); } else if(test(expr[i])==2) {

if(empty()) push(expr[i]); else

{ while(ref(top())>=ref(expr[i])) {

temp[0]=pop();temp[1]=’\0’;insert_last(temp,1);

} push(expr[i]);

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 7 Lớp 06T4

Page 8: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

} }

i++;}

if(!empty()){ while(S!=NULL) { temp[0]=pop(); temp[1]=’\0’;

insert_last(temp,1); };}return;

} Dĩ nhiên là thuật toán được trình bày trên đây là khá đơn giản và chưa ứng dụng

được trong trường hợp biểu thức có các hàm như sin, cos,… Tuy nhiên, việc mở rộng thuật toán bao gồm số thực và các hàm sin,cos, .... xin trình bày trong phần sau.

IV. Mở rộng đề tài:Như vậy phần thuật toán cơ bản đã nêu lên nguyên lý chung trong việc giải quyết

chuyển một biểu thức từ dạng trung tố sang hậu tố đối với các toán tử +,- ,*, / số có một chữ số. Trong phần mở rộng này sẽ nói mở rộng hơn bao gồm cả số thực ( số có nhiều chứ sô), các hàm mũ, sin, cos, tg, ln..., việc kiểm tra một biểu thức có đúng không, và tính toán một biểu thức nếu biểu thức đúng.

* Khi ta xét biểu thức có liên qua tới hàm tức là sẽ phải nhập các kí tự nên ta sẽ thêm vào trong hàm kiểm tra các kí tự nhập ở đầu vào như sau:

int test(char x){ if (((x>='0')&&(x<='9'))||(x== '.')) return 1;

else if (x== '+' ||x=='-'||x=='*'||x=='/'||x=='^'||x=='%'||x=='!') return 2;else if (((x>=65)&&(x<=90)) || ((x>=97)&&(x<=122)) ) return 3; else if ( x=='(' || x==')'|| x==' ' )return 4;

else return 0; }

* Theo các quy ước toán học, ta có được thứ tự ưu tiên của các phép toán và các hàm. Giai thừa (!) có độ ư tiên lớn nhất đến mũ (^) có độ ưu tiên kém hơn nhưng nó lại ưu tiên hơn so với hàm, kế tiếp sau hàm là các dạng toán tử một ngôi mà ở đây ta dùng(#) để đánh dấu và các phép toán nhân (*) , chia (/) có độ ưu tiên hơn các phép toán (+) , trừ (-).

int ref(char x){ if (( x == '+')||(x =='-')) return 1;

else if ( ( x=='*')||(x== '/')||( x=='%')) return 2; else if( x=='#') return 3;

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 8 Lớp 06T4

Page 9: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

else if((x>='a')&&(x<='k')) return 4;else if( x=='^') return 5; else if( x=='!') return 6;else if(x=='('||x==')') return 0;

else return -1;}

* Trong hàm convert (expr) này sẽ bổ sung việc xử lý số thực, các hàm (sin, cos, ln, ^ ...), các toán hạng một ngôi ( a-+b, a* +b...).

+ Hàm menu_list( x) giúp ta rút ngắn bớt chương trình trong việc nhập chèn các hàm hoặc các toán tử vào biểu thức hậu tố.

void menu_list(char x){ char temp[10]; switch(x) { case 'a': insert_last("sin",0); break; case 'b': insert_last("cos",0); break; case 'c': insert_last("tg",0); break; case 'd': insert_last("cotg",0);break; case 'e': insert_last("ln",0); break;

case 'f': insert_last("lg",0); break; case 'g': insert_last("sqrt",0); break; case 'h': insert_last("exp",0); break; case 'k': insert_last("asin",0); break; case 'l': insert_last("acos",0); break; case 'm': insert_last("atan",0);break;

default : temp[0]=x; temp[1]='\0'; insert_last(temp,1); } return; }

+ Hàm test_am (expr, i ) sẽ thực hiện nhiệm vụ kiểm tra một toán hạng có phải là toán hạng một ngôi hay không. Hàm sẽ trả về 1 tức là toán hạng một ngôi và 0 không phải là toán hạng một ngôi.

int test_am ( char *expr,int i){ int j,ok=0,k,l,m; char *temp,*temp1; temp= new (char); temp1=new( char); if ( expr[i]=='+'||expr[i]=='-') { if ( i==0) j=i; if ( i>0 ) j=i-1; while ( expr[j]==' ') --j;

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 9 Lớp 06T4

Page 10: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

if ((( test (expr[j])==2)&&(( expr[j]=='%')||( expr[j]!='!')))||( expr[j]=='(')) ok=1;

if ( test (expr[j])==3){

k=0; while ( test(expr[j])==3)

{ temp[k]=expr[j]; j--; k++; } k--; m=0; for ( l=k; l >=0; l--) { temp1[m]=temp[l]; m++; } temp1[m]='\0'; if ( strcmpi(temp1,"pi") ==0 ) ok=0;

else if ( strcmpi(temp1,"sin") ==0 ) ok=1; else if ( strcmpi(temp1,"cos") ==0 ) ok=1; else if ( strcmpi(temp1,"tg") ==0 ) ok=1; else if ( strcmpi(temp1,"cotg")==0 ) ok=1; else if ( strcmpi(temp1,"ln") ==0 ) ok=1; else if ( strcmpi(temp1,"lg") ==0 ) ok=1;

else if ( strcmpi(temp1,"sqrt")==0 ) ok=1; else if ( strcmpi(temp1,"exp") ==0 ) ok=1; else if ( strcmpi(temp1,"asin")==0 ) ok=1; else if ( strcmpi(temp1,"acos")==0 ) ok=1; else if ( strcmpi(temp1,"atan")==0 ) ok=1; } } return ok; }

* Hàm chuyển biểu thức trung tố sang hậu tố có mở rộng.void convert(char *expr)

{ char temp[10],temp1[10]; int n,l,i,a,kt; char x; double val; create(); n=strlen(expr); i=0; while(i<n) { while(expr[i]==' '&&i<n) i++; if(expr[i]=='(') push(expr[i]);

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 10 Lớp 06T4

Page 11: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

else if(expr[i]==')') { while(top()!='(') { temp[0]=pop(); menu_list(temp[0]); } pop(); } else if(test(expr[i])==1) { l=0; while(test(expr[i])==1) { temp[l]=expr[i]; i++; l++; } i--; temp[l]='\0'; val=atof(temp); insert_last(temp,val); } else if(test(expr[i])==2) { kt=test_am(expr,i); if ( kt==1)

{ push(expr[i]); push('#'); } else { if(empty()) push(expr[i]); else

{ while(ref(top())>=ref(expr[i]))

{ temp[0]=pop();

menu_list(temp[0]); } push(expr[i]); } }

}else if(test(expr[i])==3)

{l=0;while(test(expr[i])==3)

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 11 Lớp 06T4

Page 12: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

{temp[l]=expr[i];l++; i++;

}i--;temp[l]='\0';

if(strcmpi(temp,"pi")==0 ) insert_last("PI", 3.14); else

{ if(strcmpi(temp,"sin")==0) x='a';

else if(strcmpi(temp,"cos")==0) x='b';else if(strcmpi(temp,"tg")==0) x='c';else if(strcmpi(temp,"cotg")==0)x='d';else if(strcmpi(temp,"ln")==0) x='e';else if(strcmpi(temp,"lg")==0) x='f';else if(strcmpi(temp,"sqrt")==0)x='g';else if(strcmpi(temp,"exp")==0) x='h';else if(strcmpi(temp,"asin")==0)x='k';else if(strcmpi(temp,"acos")==0)x='l';else if(strcmpi(temp,"atan")==0)x='m';

if(empty()) push(x); else { if ( test(top())==3)push(x);

else { while(ref(top())>=ref(x)) { temp[0]=pop();

menu_list(temp[0]); }

push(x); }

} }

} i++; } if(!empty()) { while(S!=NULL) { temp[0]=pop(); menu_list(temp[0]); }; } return;

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 12 Lớp 06T4

Page 13: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

} Phần tiếp theo sau đây, chúng tôi muốn mở rộng ra việc kiểm tra một biểu

thức có đúng chưa, và nếu đã đúng rồi thì hãy tính biểu thức đó.+ Hàm kiểm tra test_bt( exp) thực hiện kiểm tra biểu thức vào có đúng không, một số trường hợp biểu thức sai trong quá trình tính toán làm cho điều kiện của một biểu thức bị vi phạm ( 5 / (2-2) làm cho mẫu số của biểu thức bằng 0=> biểu thức sai, và điều này sẽ được kiểm tra trong quá trình tính toán ở hàm calculate( ) ở phần sau)và hàm sẽ trả về giá trị 1 nếu biểu thức đúng và trả về 0 nếu biểu thức sai.Ví dụ:

2++ , ( ), 2..322 , 2.3! , sin 5+/ 1, (2+5)/2+(2 , 2^*3 ,...........int test_bt( char *exp)

{ int i, j, m,k,l, ok=1,n=0, z=0; char *temp,temp1[10]; float val, val1; temp=new(char); m=strlen(exp); i=0; while ( i<m ) { if ( test(exp[i])==0)return 0; while ( exp[i]==' ' && i<m )i++; if ( i==m) return 0; if ( test(exp[i])==1) { k=0; while( test(exp[i])==1) { temp[k]=exp[i]; k++; i++; } Temp[k]='\0'; j=0; for ( l=0; l<k ; l++) { if ( temp[l]=='.')j++; if ( j>1) return 0; } val=atof(temp); val1=ceil(val); if(val1!=val) { while ( exp[i]==' ' && i<m )i++; if( exp[i]=='%'||exp[i]=='!') return 0; l=i-k-1;

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 13 Lớp 06T4

Page 14: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

while ( exp[l]==' ' && l>=0) l--; if ( exp[l]=='%') return 0; } while ( exp[i]==' ' && i<m )i++; if (( test(exp[i])==3)|| exp[i]=='(') return 0; } else if ( test(exp[i])==3) { k=0; while ( test(exp[i])==3) { temp[k]=exp[i]; k++; i++; } temp[k]='\0'; if ( strcmpi(temp,"pi") ==0 )

{while ( exp[i]==' ' && i<m )i++;

if (( test(exp[i])==1)||( test(exp[i])==3)|| exp[i]=='(') return 0;if ( i==m) return 1;

} else if ( strcmpi(temp,"sin") ==0 ) ok=0; else if ( strcmpi(temp,"cos") ==0 ) ok=0; else if ( strcmpi(temp,"tg") ==0 ) ok=0; else if ( strcmpi(temp,"cotg")==0 ) ok=0; else if ( strcmpi(temp,"ln") ==0 ) ok=0; else if ( strcmpi(temp,"lg") ==0 ) ok=0; else if ( strcmpi(temp,"sqrt")==0 ) ok=0; else if ( strcmpi(temp,"exp") ==0 ) ok=0; else if ( strcmpi(temp,"asin")==0 ) ok=0; else if ( strcmpi(temp,"acos")==0 ) ok=0; else if ( strcmpi(temp,"atan")==0 ) ok=0; else

{ ok=1;

if ( ok==1 ) return 0; while ( exp[i]==' ' && i<m )i++; if ( test(exp[i])==2 && exp[i]!='+' && exp[i]!= '-') return 0; if ( i==m) return 0;

} } else if ( test(exp[i])==2) { for ( l=0; l<m; l++) if ( test(exp[l])==1) z=1; if ( z==0) return 0; k=0; while (( test(exp[i])==2) && i<m )

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 14 Lớp 06T4

Page 15: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

{ temp[k]=exp[i]; k++; i++; } k--;

l=0; while ( exp[i]==' ' && i<m ){i++; l++;} if ( k<1 && temp[k]=='!'&& (test(exp[i])==1||test(exp[i])==3||exp[i]=='('))

return 0; if ( k==1 && temp[0]!='!' && temp[1]!='+' && temp[1]!='-') return 0; if ( k==1 && (temp[0]=='%'&&temp[1]!='-'&&temp[1]!='+'))return 0;

if ( k==2 && temp[2]!='+'&& temp[2]!='-') return 0; if ( k>2) return 0; if ( exp[i-l-1]!='!'&& exp[i]==')') return 0;

if( i==m && exp[i-1-l]!='!') return 0; } else if ( exp[i]=='(') { if ( exp[i]=='(') n++; i++; while ( exp[i]==' ' && i<m )i++; if ( exp[i]==')') return 0; if ( i==m) return 0; if ( test(exp[i])==2 && exp[i]!='+' && exp[i]!='-') return 0; } else if ( exp[i]==')') { if (exp[i]==')'&& i==0) return 0; else n--; i++; while ( exp[i]==' ' && i<m )i++; } } if ( n!=0) return 0; return 1; }

+ Các hàm sau đây thực hiện nhiệm vụ tính toán một biểu thức:Quá trình tính toán giá trị của biểu thức hậu tố khá tự nhiên đối với máy tính. Ý tưởng là đọc biểu thức từ trái sang phải, nếu gặp một toán hạng (con số hoặc biến) thì push toán hạng này vào ngăn xếp; nếu gặp toán tử, lấy hai toán hạng ra khỏi ngăn xếp (stack), tính kết quả, đẩy kết quả trở lại ngăn xếp. Khi quá trình kết thúc thì con số cuối cùng còn lại trong ngăn xếp chính là giá trị của biểu thức đó.

* Xây dựng ngăn xếp tính kết quả từ biểu thức hậu tố nêu trên.struct tinh

{double x;

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 15 Lớp 06T4

Page 16: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

tinh *next;};tinh *T;long giaithua(int n){ if(n==0||n==1) return 1; else return n*giaithua(n-1);}

* Hàm thực hiện việc đẩy phần tử vào trong stack Tvoid push_T(double x){ tinh *new_ele;

new_ele=new(tinh); new_ele->x=x; new_ele->next=NULL; if(T==NULL) T=new_ele; else { new_ele->next=T; T=new_ele; }return;

}* Hàm đọc ra một phần tử trên đỉnh stack T:

double pop_T(){ tinh *cur; double x;

if(T==NULL) return 0;else { cur=T;

x=T->x; T=T->next; delete(cur);

}return x;

} * Hàm thực hiện tính toán và trong hàm này cũng kèm theo việc kiểm tra

biểu thức tránh trường hợp suy biến do tính toán: void calculate(){ double x1,x2,s; int ok=1; hauto *cur; T=NULL; cur=P;

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 16 Lớp 06T4

Page 17: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

while(cur!=NULL) {

if ( strcmp(cur->letter,"#")==0) { x1=pop_T(); cur=cur->next; if ( strcmp(cur->letter,"-")==0) { s=0-x1; push_T(s); } else if (strcmp(cur->letter,"+")==0) { push_T(x1); } } else if(strcmp(cur->letter,"+")==0)

{ x2=pop_T(); x1=pop_T(); s=x1+x2; push_T(s);

} else if(strcmp(cur->letter,"-")==0)

{ x2=pop_T(); x1=pop_T();

s=x1-x2; push_T(s);

} else if(strcmp(cur->letter,"*")==0) {

x2=pop_T(); x1=pop_T(); s=x1*x2; push_T(s);

}else if(strcmp(cur->letter,"/")==0)

{ x2=pop_T(); if(x2!=0)

{ x1=pop_T(); s=x1/x2; push_T(s);

} else {

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 17 Lớp 06T4

Page 18: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

ok=0; break;

}}else if(strcmp(cur->letter,"%")==0){ x2=pop_T();

if ( x2==0) { ok=0;

break; }

else { x1=pop_T(); s=(int)x1%(int)x2;

push_T(s); }

}else if(strcmp(cur->letter,"^")==0){ x2=pop_T();

x1=pop_T(); if ( x2==0&&x1==0)

{ ok=0;

break; }

else {

s=pow(x1,x2);push_T(s);

} }else if(strcmp(cur->letter,"!")==0){ x1=pop_T();

if(x1<0) { ok=0;

break; } else {

s=giaithua((int)x1);push_T(s);

}}

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 18 Lớp 06T4

Page 19: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

else if(strcmp(cur->letter,"sin")==0) { x1=pop_T();

s=sin(x1); push_T(s);

} else if(strcmp(cur->letter,"cos")==0){ x1=pop_T();

s=cos(x1); push_T(s);

} else if(strcmp(cur->letter,"tg")==0){ x1=pop_T(); if ( cos (x1) ==0 )

{ ok=0;

break; }

else { s=tan(x1); push_T(s); }

} else if(strcmp(cur->letter,"cotg")==0){ x1=pop_T(); if ( sin (x1) ==0)

{ ok=0;

break; }

else { s=1.0/tan(x1); push_T(s); }

} else if(strcmp(cur->letter,"ln")==0)

{ x1=pop_T(); if( x1 >0)

{ s=log(x1); push_T(s); }

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 19 Lớp 06T4

Page 20: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

else { ok=0;

break; }

}else if(strcmp(cur->letter,"lg")==0){

x1=pop_T(); if( x1 >0) { s=log10(x1);

push_T(s); } else { ok=0;

break; }

}else if(strcmp(cur->letter,"sqrt")==0){

x1=pop_T();if ( x1 <0 )

{ ok=0;

break; }

else {

s=sqrt(x1);push_T(s);

}}

else if(strcmp(cur->letter,"exp")==0){ x1=pop_T();

s=exp(x1);push_T(s);

} else if(strcmp(cur->letter,"asin")==0){

x1=pop_T();s=asin(x1);push_T(s);

}else if(strcmp(cur->letter,"acos")==0){

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 20 Lớp 06T4

Page 21: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

x1=pop_T();s=acos(x1);push_T(s);

}else if(strcmp(cur->letter,"atan")==0){

x1=pop_T();s=atan(x1);push_T(s);

} else push_T(cur->value);cur=cur->next;

} textcolor(3); if (ok) cprintf("%.3lf",pop_T()); else cprintf(" Bieu thuc sai( kq).."); return;}

Đề tài này có thể mở rộng hơn nữa trong việc xử lý biến. Ở đây chúng tôi xin nêu ra hướng giải quyết đối với trường hợp này thôi.

Khi một dãy kí tự vừa số mà không phải các số, toán tử, cũng không phải hàm , hay hằng số (pi) thì ta thực hiện việc kiểm tra một kí tự tiếp theo có phải là kí tự ‘=’ không, nếu đúng ta thực hiện lưu giá trị này vào một danh sách liên kết riêng B có kiểu cấu trúc gồm 3 trường: name, value, next và khi gặp lại biến này nó thực hiện việc lấy lại giá trị trong danh sách liên kết B. Khi xét một xâu vào thì chúng ta có thể xảy ra biến đã được khai báo hoặc chưa được khai báo, tuỳ trường hợp mà ta đưa ra các thông báo khác nhau cho người dùng.

V. Viết chương trình:#include <stdio.h>#include <conio.h>#include <stdlib.h>#include <string.h>#include <math.h>

#define Left 10#define Top 10#define Row 5#define Column 6#define mau_khung 10 #define mau_phim12 #define BackGround 9 /*-------------------------------------------------------------------*/struct toantu{

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 21 Lớp 06T4

Page 22: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

char tt;toantu *next;

} ;struct hauto{

char letter[10];double value;hauto *next;

};/*-------------------------------------------------------------------*/struct tinh{

double x;tinh *next;

};/*-------------------------------------------------------------------*/typedef toantu *stack;typedef hauto *list;stack S;list P;tinh *T;/*-------------------------------------------------------------------*/char* btnControl[5][6]={{" Sin "," Cos "," Tg "," Cotg"," Lg "," Ln "},{" asin"," acos"," atan"," Sqrt"," ( ) "," . "},{" Exp "," x^y "," % "," 7 "," 8 "," 9 "},{" ! "," + "," - "," 6 "," 5 "," 4 "},{" / "," * "," 0 "," 1 "," 2 "," 3 "}};/*-------------------------------------------------------------------*/void Khung ( int left , int top , int width, int height, int color ); void Khung_1( int left , int top , int width, int height, int color ); void write_string ( char *str, int x, int y, int color);void keyboard();void gioithieu();void create();int empty();void push(char x);char pop();char top();int test_am ( char *expr,int i); void insert_last(char x,double val);int ref(char x);int test(char x);void convert(char *expr);void display();void calculate();double pop_T();

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 22 Lớp 06T4

Page 23: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

void push_T(double x);long giaithua(int n);int menu();void menu_list(char x);int test_bt(char *exp);/*-------------------------------------------------------------------*/main(){ textbackground(1); char expr[50]; int key; gioithieu(); do { clrscr(); keyboard(); fflush(stdin); textcolor(3); gets(expr);

if ( strlen(expr)&&(strcmpi(expr, "exit")!=0)) if (test_bt(expr)) {

convert(expr); gotoxy(Left+1,Top-2);textcolor(3);

display(); gotoxy(Left+Column*5+3,Top-5);textcolor(3); calculate(); } else { write_string ("bieu thuc sai ( do nhap)...",Left+1,Top-5,3); } else return 0; getch();

}while(1); return 1;}/*-------------------------------------------------------------------*/void Khung ( int left , int top , int width, int height, int color ){ int i; textcolor(color); gotoxy(left, top); putch(201); gotoxy(left, top+height+1); putch(200); gotoxy(left+width+1, top); putch(187); gotoxy(left+width+1, top+height+1); putch(188);

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 23 Lớp 06T4

Page 24: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

for (i=1;i <=width; i++) { gotoxy(left+i, top); putch(205); gotoxy(left+i, top+height+1); putch(205); } for ( i=1; i<=height ; i++) { gotoxy( left, top+i); putch(186); gotoxy( left+width+1, top+i); putch(186); } return ; }/*-------------------------------------------------------------------*/ void write_string ( char *str, int x, int y, int color) {

textcolor(color);gotoxy(x, y);cprintf(str);return;

}/*-------------------------------------------------------------------*/ void gioithieu() { clrscr(); Khung ( 20, 3 , 40 , 2, 2);

Khung ( 20, 9 , 40 , 3, 2); Khung ( 20, 16 , 40 , 5, 2); write_string(" Truong Dai Hoc Bach Khoa Da Nang ", 23, 4 , 11); write_string(" Khoa Cong Nghe Thong Tin ", 23, 5 , 11);

write_string(" De tai: ",23, 10 ,11); write_string(" Ki phap Balan ",32, 11 ,11);

write_string(" Chuyen bieu thuc trung to sang hau to ",22, 12 ,11); write_string(" GVHD : LE QUY LOC",23, 17 ,11); write_string(" NHOM : 11",23, 18 ,11); write_string(" LOP : 06T4",23, 19 ,11); write_string(" HO TEN SV: HOANG XUAN KHANH",23, 20 ,11); write_string(" BUI VAN MINH ",23, 21 ,11); textcolor(7); gotoxy(10,24); cprintf("\n Ban hay nhan mot phim bat ki......."); getch();

return; } /*-------------------------------------------------------------------*/

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 24 Lớp 06T4

Page 25: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

void Khung_1(int left, int top, int width, int height, int color){ textcolor(color); gotoxy(left,top); putch(218);

gotoxy(left,top+height+1); putch(192); gotoxy(left+width+1,top); putch(191); gotoxy(left+width+1,top+height+1); putch(217); for(int i=1;i<=width;i++) { gotoxy(left+i,top);

putch(196); gotoxy(left+i,top+height+1); putch(196); } for(int j=1;j<=height;j++) { gotoxy(left,top+j); putch(179); gotoxy(left+width+1,top+j); putch(179); } return;}/*-------------------------------------------------------------------*/void keyboard(){ Khung_1(Left-1,Top-8,Column*6+6,Row*4+2,RED); write_string("My Calculator !",Left+6,Top-7,14); Khung_1(Left,Top-6,Column*5-1,1,mau_khung);cprintf("="); Khung_1(Left+Column*5+2,Top-6,8,1,mau_khung); Khung_1(Left,Top-3,Column*6+4,1,mau_khung);

textbackground(BackGround);write_string("Note:",Left+Column*7+2,Row*4,14); write_string("Exit: Thoat",Left+Column*7+2,Row*4+2,14);

int width=5,height=1; for (int i=0;i<Row;i++)

for (int j=0;j<Column;j++) { Khung_1(Left+j*(width+2),Top+i*(height+2),width,height,mau_khung); write_string(btnControl[i][j],Left+j*(width+2)+1,Top+i*(height+2)+1,mau_phim); } gotoxy(Left+1,Top-5); return;}

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 25 Lớp 06T4

Page 26: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

/*-------------------------------------------------------------------*/void create(){

S=NULL;P=NULL;return;

}/*-------------------------------------------------------------------*/int empty(){

return(S==NULL);}/*-------------------------------------------------------------------*/void push(char x){ toantu *new_ele;

new_ele=new(toantu);new_ele->tt=x;new_ele->next=NULL;if(empty())

{ S=new_ele;

new_ele->next=NULL; } else {

new_ele->next=S; S=new_ele; } return;}/*-------------------------------------------------------------------*/char pop(){ toantu *cur; char x;

if (empty ( )) return 0; else

{ x = S->tt;

cur =S; S = S->next; delete(cur); } return x; }/*-------------------------------------------------------------------*/char top()

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 26 Lớp 06T4

Page 27: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

{ char x;

if (!empty( ) ) x=S->tt; return(x); }/*-------------------------------------------------------------------*/void insert_last(char *x,double val){ hauto *cur;

hauto *new_ele; new_ele=new(hauto); strcpy(new_ele->letter,x); new_ele->value=val;

new_ele->next=NULL;if(P==NULL)

{ P=new_ele; } else {

cur=P;while(cur->next!=NULL) cur=cur->next;

cur->next=new_ele; } return;}/*-------------------------------------------------------------------*/

int ref(char x){ if (( x == '+')||(x =='-')) return 1;

else if ( ( x=='*')||(x== '/')||( x=='%')) return 2; else if( x=='#') return 3;

else if((x>='a')&&(x<='k')) return 4;else if( x=='^') return 5; else if( x=='!') return 6;else if(x=='('||x==')') return 0;

else return -1;}/*-------------------------------------------------------------------*/int test(char x){ if (((x>='0')&&(x<='9'))||(x== '.')) return 1;

else if (x== '+' ||x=='-'||x=='*'||x=='/'||x=='^'||x=='%'||x=='!') return 2;else if (((x>=65)&&(x<=90)) || ((x>=97)&&(x<=122)) ) return 3; else if ( x=='(' || x==')'|| x==' ' )return 4;

else return 0; }/*-------------------------------------------------------------------*/

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 27 Lớp 06T4

Page 28: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

int test_bt( char *exp) { int i, j, m,k,l, ok=1,n=0, z=0; char *temp,temp1[10]; float val, val1; temp=new(char); m=strlen(exp); i=0; while ( i<m ) { if ( test(exp[i])==0)return 0; while ( exp[i]==' ' && i<m )i++; if ( i==m) return 0; if ( test(exp[i])==1) { k=0; while( test(exp[i])==1) { temp[k]=exp[i]; k++; i++; } temp[k]='\0'; j=0; for ( l=0; l<k ; l++) { if ( temp[l]=='.')j++; if ( j>1) return 0; } val=atof(temp); val1=ceil(val); if(val1!=val) { while ( exp[i]==' ' && i<m )i++; if( exp[i]=='%'||exp[i]=='!') return 0; l=i-k-1; while ( exp[l]==' ' && l>=0) l--; if ( exp[l]=='%') return 0; } while ( exp[i]==' ' && i<m )i++; if (( test(exp[i])==3)|| exp[i]=='(') return 0; } else if ( test(exp[i])==3) { k=0; while ( test(exp[i])==3) { temp[k]=exp[i];

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 28 Lớp 06T4

Page 29: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

k++; i++; } temp[k]='\0'; if ( strcmpi(temp,"pi") ==0 )

{while ( exp[i]==' ' && i<m )i++;

if (( test(exp[i])==1)||( test(exp[i])==3)|| exp[i]=='(') return 0;if ( i==m) return 1;

} else if ( strcmpi(temp,"sin") ==0 ) ok=0; else if ( strcmpi(temp,"cos") ==0 ) ok=0; else if ( strcmpi(temp,"tg") ==0 ) ok=0; else if ( strcmpi(temp,"cotg")==0 ) ok=0; else if ( strcmpi(temp,"ln") ==0 ) ok=0; else if ( strcmpi(temp,"lg") ==0 ) ok=0; else if ( strcmpi(temp,"sqrt")==0 ) ok=0; else if ( strcmpi(temp,"exp") ==0 ) ok=0; else if ( strcmpi(temp,"asin")==0 ) ok=0; else if ( strcmpi(temp,"acos")==0 ) ok=0; else if ( strcmpi(temp,"atan")==0 ) ok=0; else

{ ok=1;

if ( ok==1 ) return 0; while ( exp[i]==' ' && i<m )i++; if ( test(exp[i])==2 && exp[i]!='+' && exp[i]!= '-') return 0; if ( i==m) return 0;

} } else if ( test(exp[i])==2) { for ( l=0; l<m; l++) if ( test(exp[l])==1) z =1; if ( z==0) return 0; k=0; while (( test(exp[i])==2) && i<m ) { temp[k]=exp[i]; k++; i++; } k--; l=0; while ( exp[i]==' ' && i<m ){i++; l++;} if ( k<1 && temp[k]=='!'&& (test(exp[i])==1||test(exp[i])==3||exp[i]=='('))

return 0; if ( k==1 && temp[0]!='!' && temp[1]!='+' && temp[1]!='-') return 0; if ( k==1 && (temp[0]=='%'&&temp[1]!='-'&&temp[1]!='+')|| (temp[0]=='/'&& temp[1]=='-'))return 0;

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 29 Lớp 06T4

Page 30: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

if ( k==2 && temp[2]!='+'&& temp[2]!='-') return 0; if ( k>2) return 0; if ( exp[i-l-1]!='!'&& exp[i]==')') return 0;

if( i==m && exp[i-1-l]!='!') return 0; } else if ( exp[i]=='(') { if ( exp[i]=='(') n++; i++; while ( exp[i]==' ' && i<m )i++; if ( exp[i]==')') return 0; if ( i==m) return 0; if ( test(exp[i])==2 && exp[i]!='+' && exp[i]!='-') return 0; } else if ( exp[i]==')') { if (exp[i]==')'&& i==0) return 0; else n--; i++; while ( exp[i]==' ' && i<m )i++; } } if ( n!=0) return 0; return 1; }/*-------------------------------------------------------------------*/void menu_list(char x){ char temp[10]; switch(x) { case 'a': insert_last("sin",0); break; case 'b': insert_last("cos",0); break; case 'c': insert_last("tg",0); break; case 'd': insert_last("cotg",0);break; case 'e': insert_last("ln",0); break; case 'f': insert_last("lg",0); break; case 'g': insert_last("sqrt",0); break; case 'h': insert_last("exp",0); break; case 'k': insert_last("asin",0); break; case 'l': insert_last("acos",0); break; case 'm': insert_last("atan",0);break;

default : temp[0]=x; temp[1]='\0'; insert_last(temp,1); } return;

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 30 Lớp 06T4

Page 31: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

} /*-------------------------------------------------------------------*/int test_am ( char *expr,int i){ int j,ok=0,k,l,m; char *temp,*temp1; temp= new (char); temp1=new( char); if ( expr[i]=='+'||expr[i]=='-') { if ( i==0) j=i; if ( i>0 ) j=i-1; while ( expr[j]==' ') --j; if ((( test (expr[j])==2)&&(( expr[j]=='%')||( expr[j]!='!')))||( expr[j]=='('))

ok=1; if ( test (expr[j])==3)

{ k=0;

while ( test(expr[j])==3) { temp[k]=expr[j]; j--; k++; } k--; m=0; for ( l=k; l >=0; l--) { temp1[m]=temp[l]; m++; } temp1[m]='\0'; if ( strcmpi(temp1,"pi") ==0 ) ok=0;

else if ( strcmpi(temp1,"sin") ==0 ) ok=1; else if ( strcmpi(temp1,"cos") ==0 ) ok=1; else if ( strcmpi(temp1,"tg") ==0 ) ok=1; else if ( strcmpi(temp1,"cotg")==0 ) ok=1; else if ( strcmpi(temp1,"ln") ==0 ) ok=1; else if ( strcmpi(temp1,"lg") ==0 ) ok=1;

else if ( strcmpi(temp1,"sqrt")==0 ) ok=1; else if ( strcmpi(temp1,"exp") ==0 ) ok=1; else if ( strcmpi(temp1,"asin")==0 ) ok=1; else if ( strcmpi(temp1,"acos")==0 ) ok=1; else if ( strcmpi(temp1,"atan")==0 ) ok=1; } } return ok; }/*-------------------------------------------------------------------*/

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 31 Lớp 06T4

Page 32: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

void convert(char *expr){ char temp[10],temp1[10]; int n,l,i,a,kt; char x; double val; create(); n=strlen(expr); i=0; while(i<n) { while ( expr[i]==' '&& i<n ) i++; if ( expr[i] == '(' ) push ( expr[i] ); else if ( expr[i]== ')' ) { while ( top( ) != '(' ) { temp[0]=pop();

menu_list(temp[0]); } pop(); } else if ( test(expr[i]) == 1 ) { l=0; while ( test ( expr[i] ) ==1 ) { temp[l]=expr[i];

i++; l++; } i--; temp[l] = '\0'; val = atof ( temp ); insert_last ( temp, val ); } } else if(test(expr[i])==2) { kt=test_am(expr,i); if ( kt==1)

{ push(expr[i]); push('#'); } else { if(empty()) push(expr[i]); else

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 32 Lớp 06T4

Page 33: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

{ while(ref(top())>=ref(expr[i]))

{ temp[0]=pop();

menu_list(temp[0]); } push(expr[i]); } }

}else if(test(expr[i])==3)

{l=0;while(test(expr[i])==3){

temp[l]=expr[i];l++; i++;

}i--;temp[l]='\0';

if(strcmpi(temp,"pi")==0 ) insert_last("PI", 3.14); else

{ if(strcmpi(temp,"sin")==0) x='a';

else if(strcmpi(temp,"cos")==0) x='b';else if(strcmpi(temp,"tg")==0) x='c';else if(strcmpi(temp,"cotg")==0)x='d';else if(strcmpi(temp,"ln")==0) x='e';else if(strcmpi(temp,"lg")==0) x='f';else if(strcmpi(temp,"sqrt")==0)x='g';else if(strcmpi(temp,"exp")==0) x='h';else if(strcmpi(temp,"asin")==0)x='k';else if(strcmpi(temp,"acos")==0)x='l';else if(strcmpi(temp,"atan")==0)x='m';

if(empty()) push(x); else { if ( test(top())==3)push(x);

else { while(ref(top())>=ref(x)) { temp[0]=pop();

menu_list(temp[0]); }

push(x); }

}

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 33 Lớp 06T4

Page 34: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

} } i++; } if(!empty()) { while(S!=NULL) { temp[0]=pop(); menu_list(temp[0]); }; } return;} /*-------------------------------------------------------------------*/void display( ){

hauto *cur;cur=P;while (cur!= NULL ){

cprintf(" %s", cur->letter);cur= cur->next;

}return;

} /*-------------------------------------------------------------------*/long giaithua(int n){ if(n==0||n==1) return 1; else return n*giaithua(n-1);}/*-------------------------------------------------------------------*/void push_T(double x){ tinh *new_ele;

new_ele=new(tinh); new_ele->x=x; new_ele->next=NULL; if(T==NULL) T=new_ele; else { new_ele->next=T; T=new_ele; }return;

}/*-------------------------------------------------------------------*/

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 34 Lớp 06T4

Page 35: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

double pop_T(){ tinh *cur; double x;

if(T==NULL) return 0;else { cur=T;

x=T->x; T=T->next; delete(cur);

}return x;

} /*-------------------------------------------------------------------*/void calculate(){ double x1,x2,s; int ok=1; hauto *cur; T=NULL; cur=P; while(cur!=NULL) {

if ( strcmp(cur->letter,"#")==0) { x1=pop_T(); cur=cur->next; if ( strcmp(cur->letter,"-")==0) { s=0-x1; push_T(s); } else if (strcmp(cur->letter,"+")==0) { push_T(x1); } } else if(strcmp(cur->letter,"+")==0)

{ x2=pop_T(); x1=pop_T(); s=x1+x2; push_T(s);

} else if(strcmp(cur->letter,"-")==0)

{ x2=pop_T();

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 35 Lớp 06T4

Page 36: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

x1=pop_T(); s=x1-x2;

push_T(s);}

else if(strcmp(cur->letter,"*")==0) {

x2=pop_T(); x1=pop_T(); s=x1*x2; push_T(s);

}else if(strcmp(cur->letter,"/")==0)

{ x2=pop_T(); if(x2!=0)

{ x1=pop_T(); s=x1/x2; push_T(s);

} else { ok=0;

break; }

}else if(strcmp(cur->letter,"%")==0){ x2=pop_T();

if ( x2==0) { ok=0;

break; }

else { x1=pop_T(); s=(int)x1%(int)x2;

push_T(s); }

}else if(strcmp(cur->letter,"^")==0){ x2=pop_T();

x1=pop_T(); if ( x2==0&&x1==0)

{ ok=0;

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 36 Lớp 06T4

Page 37: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

break; }

else {

s=pow(x1,x2);push_T(s);

} }else if(strcmp(cur->letter,"!")==0){ x1=pop_T();

if(x1<0) { ok=0;

break; } else {

s=giaithua((int)x1);push_T(s);

}}else if(strcmp(cur->letter,"sin")==0) { x1=pop_T();

s=sin(x1); push_T(s);

} else if(strcmp(cur->letter,"cos")==0){ x1=pop_T();

s=cos(x1); push_T(s);

} else if(strcmp(cur->letter,"tg")==0){ x1=pop_T(); if ( cos (x1) ==0 )

{ ok=0;

break; }

else { s=tan(x1); push_T(s); }

}

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 37 Lớp 06T4

Page 38: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

else if(strcmp(cur->letter,"cotg")==0){ x1=pop_T(); if ( sin (x1) ==0)

{ ok=0;

break; }

else { s=1.0/tan(x1); push_T(s); }

} else if(strcmp(cur->letter,"ln")==0)

{ x1=pop_T(); if( x1 >0)

{ s=log(x1); push_T(s); } else { ok=0;

break; }

}else if(strcmp(cur->letter,"lg")==0){

x1=pop_T(); if( x1 >0) { s=log10(x1);

push_T(s); } else { ok=0;

break; }

}else if(strcmp(cur->letter,"sqrt")==0){

x1=pop_T();if ( x1 <0 )

{ ok=0;

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 38 Lớp 06T4

Page 39: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

break; }

else {

s=sqrt(x1);push_T(s);

}}

else if(strcmp(cur->letter,"exp")==0){ x1=pop_T();

s=exp(x1);push_T(s);

} else if(strcmp(cur->letter,"asin")==0){

x1=pop_T();s=asin(x1);push_T(s);

}else if(strcmp(cur->letter,"acos")==0){

x1=pop_T();s=acos(x1);push_T(s);

}else if(strcmp(cur->letter,"atan")==0){

x1=pop_T();s=atan(x1);push_T(s);

} else push_T(cur->value);cur=cur->next;

} textcolor(3); if (ok) cprintf("%.3lf",pop_T()); else cprintf(" Bieu thuc sai( kq).."); return;} /***********************END**********************//*************************************************/

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 39 Lớp 06T4

Page 40: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

VI. Kết quả chương trình:Giao điện của chương trình:

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 40 Lớp 06T4

Page 41: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

VII. Kết luận:Đề tài trên đã giải quyết việc chuyển một biểu thức từ trung tố sang hậu tố với

thuật toán đơn giản, dễ hiểu. Đồng thời mở rộng thêm nhiều nhưng theo chúng tôi, nó vẫn còn các thiếu sót như trong việc kiểm tra các điều kiện ràng buộc, các trường hợp đặc biệt khác...

Để bài làm có thể dễ nhìn và đẹp mắt, chúng tôi có sử dụng thêm các đồ hoạ văn bản.

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 41 Lớp 06T4

Page 42: baocao

ĐỒ ÁN CẤU TRÚC DỮ LIỆU GV: Lê Quý Lộc

VIII. Nhận xét của giáo viên hướng dẫn:................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................

Bùi Văn Minh _ Hoàng Xuân Khánh Trang: 42 Lớp 06T4