Ký pháp nghịch đảo Balan Khái niệm về ký

Một phần của tài liệu đồ án công nghệ thông tin Cách sử dụng email , hệ thống mạng LAN (Trang 96 - 110)

V I Hạn Chế Mất Thông Tin Thiết Lậ pT

g cho folder của bạn.

I.1. ký pháp nghịch đảo Balan Khái niệm về ký

I.1. ký pháp nghịch đảo Balan.Khái niệm về ký Khái niệm về ký

háp nghịch đảo Balan(RPN).

- Ký pháp nghịch đảo Balan còn được gọi là Postfix do Charles Hamblin để xuất vào những năm 1950. Ký pháp này lấy ý tưởng của Polish notation được đề xuất vào nhưng năm 1920

A-B/(C+D) ABCD-/+ -A/B+CD

nh toán học người Balan 1. 2. Tại sao sử d

g ký pháp nghịch đảo Balan.

- RPN cho phép giảm thời gian tính toán của một biểu thức. người dùng không cần quan tâm đến dấu ngoặc trong biểu thức. với ký pháp này cho phép thấy kết quả ngay sau phép toán.và việc thực hiện phép toán trên máy tính tỏ ra hiệu quả hơn. Với việc cho thấy kết quả ngay, do đó người sử dụng có thể kiểm tra kết quả dễ hơn nhanh hơn. Với cách viết này việc tính toán dựa trên thứ tự của biểu thức, kết hợp với thứ tự ưu tiên của phép toán . RPN có tính logic cao vì người dựng đưa vào biểu thức rồi

u đó đưa phép tính cần thực hiện. Xem xé

một biể

thức dạng infix như sau: 1+2*3=? Kết quả là 7 vì phép nhân(*) ó độ ưu tiê cao hơn phép cộng(+) Tiếp ví dụ: (1+2)*3=? Kết quả là 9 Rõ ràng với dạng ký pháp này n dng dễ nhầm lẫn trong tính toán! 1. 3. Một ố ví dụ về ký pháp nghịch đảo alan. Xét một ví dụ RPN sau: 4 5+6 Kết q 4+5=9 của 9*6=54

ểu thức là bao nhiêu: 4 5 +

9 6*

biểu thức dạng in x sau: 4+5) . Các bước thực hiện 4 5+6* 9 6* 54 I

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

g 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ố hoặc biến) thì ghi nó vào chuỗi kết q (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

ử (gọi là o1 ), thực hiện hai bước sau:

o 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ấ

o2 ra khỏi ngăn xếp và hi vào kết quả.

o 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 k

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

từnăn xếp ra và ghi vào chuỗi kế

quả.

II I . Định giá biểu thức hậu tố.

Biểu thức hậu tố 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

ố: 4+5 sẽ được biểu diễn lại thành 4 5 +.

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

găn xếp chính là giá trị củ biểu thức đó. Ví dụ: iểu thức trung tố : 5 + ((1 + 2) * 4) 3 được biểu di li dưới dạng hậu tố à: 1 2 + 4 * + 3 #include<conio.h> #include<math.h> #include<ctype.h> #include<string.h> #include<stdlib.h> float number[200]={0}; IV . Cài ặt thuật toán. #include<std

.h> int n=0;

/* chuyen sang dang ha to*/

char st[100];

/*Ham cho queue Char*/

ar queueChar[200]={'@'};int first=0,last ;

int isEmptyQueueChar(){return las =0;}; void emptyQueu har(){las first=0;} void baoloi(char *x){ rscr(); getch(); rintf(" Khon }

// Ham dung cho queue, queue la ket qua cua qua trinh phan tich sang hau to void pushQueueChar(char x){ last++; queueChar[last]=x; } char getQueueChar(){ last++;

return queueChar[last-1]; }

/*====================================*/

// Stack dung de lam bo nho tam, phuc vu cho qua trinh phan tich sang hau to char stack[200],top=0;

void empty(){ // Khoi tao stack top=0;

}

int isemptyStack(){ //Kiem tra stack co rong return top==0;

}

void pushStack(char x){ //Dua mot ky tu vao stack top+=1;

stack[top]=x; }

char popStack(){ // Lay ky tu ra top-=1;

return stack[top+1]; }

char getStack(){ // xem ky tu dinh return stack[top];

}

int priority(char x){// Tinh muc uu tien

if(strchr("!~SCTPELaA",toupper(x)))return 4;//Cac phep toan 1 hang tu uu tien cao nhat

if(strchr("*/^%&|\\",toupper(x)))return 3; if(x=='+' || x=='-')return 2;

if(x=='(' || x==')')return 1;

return -1; }

//Ham lay 1 so tu chuoi

// vi du 12+36, so o vi tri tu 3~4 la 36 float getNumber(int b,int e){

int i;

char x[20]={0};

for(i=b;i<=e;i++)x[i-b]=st[i];

return atof(x);//ham co san, chuyen chuoi sang so }

//Ham nay chuyen st la phep tinh dang trung to (kieu viet tu nhien) //Sang dang hau to : la dang de tinh toan

// Vi du 1+2 chuyen thanh 1 2 + void Convert(){ empty(); emptyQueueChar();last=0; int i=0,j=0; char x; do{ switch(priority(st[i])){

case 0://So hang, cac chu so j=i+1;

while((isdigit(st[j]) || st[j]=='.'))j++; //Tim ky tu ko phai la so

number[n]=(getNumber(i,j-1)); //lay gia tri so o day pushQueueChar(-n);//Dua vao queueChar

n++; i=j-1; break;

case 1: // La dau mo/dong ngoac ( hoac ) if(st[i]=='(')pushStack('('); else do{ x=popStack(); if(x!='(') pushQueueChar(x); }while(x!='('); break;

case 2://phep toan 2 hang tu +,- Co muc uu tien thap case 3://Phep toan 1 hang tu */^...Muc uu tien cao

while(!isemptyStack() && (priority(st[i])<=priority(getStack()))) //UU tien dua */&^ truoc +- vi */ co uu tien cao hon +-

pushQueueChar(popStack()); pushStack(st[i]);

break;

case 4://cac toan tu 1 hang tu, nhu sin, cos, tan, cac hang so switch(st[i]){

case 'c':

case 'C'://Xem co phai la COS khong

if((toupper(st[i+1])=='O')&&(toupper(st[i+2])=='S')){ pushStack('c');

i+=2;

}else baoloi("Syntax error : ham khong duoc khai bao !"); break;

case 's':

case 'S'://Xem co phai la Sin ko

if((toupper(st[i+1])=='I')&&(toupper(st[i+2])=='N')){ pushStack('s');

}else baoloi("Syntax error : ham khong duoc khai bao !"); break;

case 't':

case 'T': //Co phai la tan

if((toupper(st[i+1])=='A')&&(toupper(st[i+2])=='N')){ pushStack('t');

i+=2;

}else baoloi("Syntax error : ham khong duoc khai bao !"); break;

case 'l':

case 'L'://Co the la Log, ln

if((toupper(st[i+1])=='O')&&(toupper(st[i+2])=='G')){ pushStack('l'); i+=2; }else if((toupper(st[i+1])=='N')){ pushStack('L'); i+=1;

}else baoloi("Syntax error : ham khong duoc khai bao !"); break;

case 'e':

case 'E'://neu ko phai la EXP thi la e=2.71828

if((toupper(st[i+1])=='X')&&(toupper(st[i+2])=='P')){ pushStack('e'); i+=2; }else { i++; number[n]=M_E; pushQueueChar(-n); n++;

}break; case 'p':

case 'P'://Co phai la PI if((toupper(st[i+1])=='I')){ i++; number[n]=M_PI; pushQueueChar(-n); n++; }break; case 'a': case 'A': switch(st[i+1]){ case 'c':

case 'C'://Xem co phai la COS khong

if((toupper(st[i+2])=='O')&&(toupper(st[i+3])=='S')){ pushStack('C');

i+=3;

}else baoloi("Syntax error : ham khong duoc khai bao !"); break;

case 's':

case 'S'://Xem co phai la Sin ko

if((toupper(st[i+2])=='I')&&(toupper(st[i+3])=='N')){ pushStack('S');

i+=3;

}else baoloi("Syntax error : ham khong duoc khai bao !"); break;

case 't':

case 'T': //Co phai la tan

pushStack('T'); i+=3;

}else baoloi("Syntax error : ham khong duoc khai bao !"); break; } break; case '!':pushQueueChar('!');break; case '~':pushQueueChar('~');break; }break; } i++; }while(i<strlen(st)); while(!isemptyStack())pushQueueChar(popStack()); } /*========================================================== =*/

//Ham phuc vu bao loi, tranh cac loi nhu log(0) int matherr (struct exception *a)

{

if (a->type == DOMAIN) baoloi("Loi tham so");

else baoloi(strcat("Math error : Loi khi tinh ham ",a->name)); return 0;

}

float giaithua(float x){ float t=1,i=1;

if(x!=(int)x)baoloi("Math error : Loi khi tinh giai thua cua so thuc"); else if(x>33)baoloi("Math error : So qua lon khi tinh giai thua");

for(;i<=x;i++)t*=i; return t;

}

//cac phep toan 1 toan tu nhu sin, cos, tan, giai thua float tinh1(float x,char pt){

switch(pt){

case 's':return sin(x); case 'S':return asin(x); case 'c':return cos(x); case 'C':return acos(x); case 't':return tan(x); case 'T':return atan(x); case '~':return ~((int)x); case '!':return giaithua(x); case 'l':return log10(x); case 'L':return log(x); case 'e':return exp(x); };

return 0; }

//Phep toan 2 hang tu nhu +, -, *, /, ^ .... float tinh2(float x,float y, char pt){ switch(pt){

case '+':return x+y; case '-':return x-y; case '*':return x*y;

case '%':return ((int)x)%((int)y); case '\\':return (int)x /(int) y; case '&':return (int)x&&(int) y;

case '|':return (int)x ||(int) y; case '/':

if(y==0)baoloi("Loi chia cho 0"); return x/y;

case '^':return pow(x,y); }

return 0; }

float StackTinh[200]={0};int topStackTinh=0;

void pushStackTinh(float x){topStackTinh++;StackTinh[topStackTinh]=x;} float getStackTinh(){topStackTinh--;return StackTinh[topStackTinh+1];} float tinhtoan(){ int i; float a,b,c; for(i=1;i<=last;i++) if(queueChar[i]>0){ if(priority(queueChar[i])<=3){

//neu la phep toan 2 hang tu nhu +,-,*,/,^ , priority=3 //lay ra 2 so gan nhat roi tinh toan, thay gia tri vao if(topStackTinh<2)baoloi(0); b=getStackTinh(); a=getStackTinh(); c=tinh2(a,b,queueChar[i]); pushStackTinh(c); }else{

//Neu la phep toan 1 hang tu, priority=4 //Lay ra 1 so va tinh toan, the vao if(topStackTinh<1)baoloi(0); a=getStackTinh();

c=tinh1(a,queueChar[i]); pushStackTinh(c); }

}else{

//Neu la 1 so thi dua vao stack c=number[-queueChar[i]]; pushStackTinh(c); } return c; } void xuat_hau_to(){ int i; for(i=1;i<=last;i++) if(queueChar[i]>0)printf("%c",queueChar[i]); else printf("{%g}",number[-queueChar[i]]); } void main(){ clrscr();

printf("\t Tinh gia tri bieu thuc\n Nhap bieu thuc nhu binh thuong\n"); printf(" Cac phep toan +-*/%!|^\\\n");

printf(" Cac ham sin,asin,cos,acos,tan,atan,log,ln,exp\n"); printf(" Cac hang pi=3.1415926535, e=2.718281828\n"); printf("\n\n\n\n St = ");gets(st); //Doc phep toan

Convert(); //Chuyen sang hau to : 12+34*56 --> 12 34 56 * + printf("\n Dang hau to : ");

xuat_hau_to();printf("\n");

printf("\n\n\n\n %s = %g",st,tinhtoan()); getch();

Một phần của tài liệu đồ án công nghệ thông tin Cách sử dụng email , hệ thống mạng LAN (Trang 96 - 110)

Tải bản đầy đủ (DOC)

(110 trang)
w