算術表示式求值-資料結構-C語言
阿新 • • 發佈:2018-11-29
1.實驗目的
熟練掌握棧的基本操作,深入瞭解棧的特性,能在實際問題的背景下靈活運用他們,並加深對這種結構的理解。
2.實驗內容
設計一個程式,演示用算符優先法對算術表示式求值的過程。以字元序列的形式從終端輸入語法正確的、不含變數的整數表示式。利用教科書表3.1給出的算符優先關係,實現對算術四則運算混合運算表示式的求值,並仿照教科書的例子3-1演示在求值中運算子棧、運算數棧、輸入字元和主要操作的變化。
#include<stdio.h> #include<stdlib.h> #define OK 1 #define ERROR 0 #define STACKINCREMENT 5 #define STACK_INIT_SIZE 10 typedef char SElemType; typedef int Status; typedef struct{ SElemType *base;//棧底指標 SElemType *top;//棧頂指標 int stacksize;//當前已經分配的儲存空間 }SqStack; char prior[7][7]={{'>','>','<','<','<','>','>'},{'>','>','<','<','<','>','>'},{'>','>','>','>','<','>','>'}, {'>','>','>','>','<','>','>'},{'<','<','<','<','<','=','!'},{'>','>','>','>','!','>','>'}, {'<','<','<','<','<','!','='}};//定義算符之間優先關係的二維陣列 //構造一個存放char型資料的空棧 Status InitStack(SqStack *s){ s->base = (SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType)); if(!s->base) return ERROR; s->top = s->base;//棧中元素個數為0 s->stacksize = STACK_INIT_SIZE; return OK; } //入棧 Status Push(SqStack *s,SElemType e){ if(s->top-s->base>=s->stacksize){ s->base = (SElemType *)realloc(s->base,(STACKINCREMENT+s->stacksize)*sizeof(SElemType)); if(!s->base) exit(0); s->top = s->base+s->stacksize; s->stacksize += STACKINCREMENT; } *s->top++ = e; return OK; } //出棧 Status Pop(SqStack *s,SElemType *e){ if(s->base==s->top){ printf("空棧!\n"); return ERROR; } *e = *--s->top; return OK; } //得到棧頂元素 SElemType GetTop(SqStack *s){ return *(s->top-1); } //確定輸入的字元如果是操作符的話判斷在二維陣列中的下標 若是數字的話就另外與操作符區分開 便於在輸入表示式時是入哪個棧 int Index(char c){ switch(c){ case '+': return 0; case '-': return 1; case '*': return 2; case '/': return 3; case '(': return 4; case ')': return 5; case '#': return 6; default: return 7; } } //判斷優先順序,返回大小 < > = ! char Priority(char a,char b){ int x,y; x = Index(a); y = Index(b); if(x!=7&&y!=7) return prior[x][y]; else return '!'; } //簡單表示式求值 int Reckon(int a,char theta,int b){ switch(theta){ case '+':return a+b; case '-':return a-b; case '*':return a*b; case '/':return a/b; } } //判斷是字元是否是數字 Status isdigit(char ch){ if(ch>='0'&&ch<='9') return OK; return ERROR; } //算術表示式求值 void GetExpressionValue(){ SqStack OPTR,OPND; SElemType result;//返回最後結果 InitStack(&OPTR); InitStack(&OPND); Push(&OPTR,'#');//將結束符置於操作符的底端 printf("請輸入算術表示式:\n"); char c = getchar(); while(c!='#'||GetTop(&OPTR)!='#'){//當*c=='#'&&棧頂字元=='#'的時候 if(isdigit(c)){//如果是數字的話將其轉化為數字 然後入運算元棧 int data[10]; int i,num; i = num =0;//num是一箇中間數 用於將字串中的數字轉化為整數然後入棧 i是用於將字串中的字元存入data陣列 while(isdigit(c)){ data[i] = c-'0'; i++; c = getchar(); } for(int j=0;j<i;j++){ num = num*10+data[j]; } Push(&OPND,num); }else{//如果是字元的話將其入操作符棧 SElemType a,b,theta;//a b theta是用來返回運算元棧和操作符棧裡的元素的 switch(Priority(GetTop(&OPTR),c)){//比較即將入棧的字元與棧頂 操作符的優先順序關係 case '<':Push(&OPTR,c); c = getchar(); break; case '>':Pop(&OPND,&b); Pop(&OPND,&a); Pop(&OPTR,&theta); Push(&OPND,Reckon(a,theta,b)); break;//將結果入棧 case '=':Pop(&OPTR,&theta); c = getchar(); break;//說明括號相遇 刪除棧內括號即可 default:break; } } } Pop(&OPND,&result); printf("結果是:%d",result); } main(){ GetExpressionValue(); }