如何用C語言計算表示式的值,棧的經典應用
阿新 • • 發佈:2018-11-11
宣告:這個程式可以計算+,-,*,/,負數,小數
負數用括號括起來例如(-1)
負數的計算過程:(-1) 轉變為 (0-1) 哈哈~
分成六個點:
1.我的檔案結構
2.順序堆疊的標頭檔案
3.標頭檔案引入與自定義的常量和型別
4.主處理函式
5.測試的主函式
6.測試結果
1.我的檔案結構
有兩個檔案 1.expCop.c 裡面的內容是:
2.SqeStack.h 裡面的內容是:棧的定義與處理函式
2.順序堆疊的標頭檔案
typedef struct{ DataType stack[MaxStackSize]; int top; }SeqStack; //棧初始化 void StackInitiate(SeqStack *S){ S->top = 0; } //判斷棧是否為空 int StackNotEmpty(SeqStack S){ if(S.top==0){ return 0; } return 1; } //入棧 int StackPush(SeqStack *S,DataType x){ if(S->top>=MaxStackSize){ printf("堆疊已滿無法插入!\n"); return 0; }else{ S->stack[S->top]=x; S->top++; return 1; } } //出棧 int StackPop(SeqStack *S,DataType *d){ if(S->top<=0){ printf("StackPop堆疊為空!\n"); return 0; }else{ S->top--; *d = S->stack[S->top]; return 1; } } //獲取棧頂資料元素 int StackTop(SeqStack S,DataType *d){ if(S.top<=0){ printf("StackTop堆疊為空!\n"); return 0; }else{ *d = S.stack[S.top-1]; return 1; } }
3.標頭檔案引入與自定義的常量和型別
typedef char DataType;//定義棧的資料存數的型別
#define MaxStackSize 100//定義棧的大小
#include <stdio.h>//這個不用多說
#include <string.h>//字串處理(自帶)
#include <math.h>//用來處理小數,用到了pow(自帶)
#include "SeqStack.h"//這是順序堆疊的標頭檔案(需要自己建立)
4.主處理函式
double expressionComputation(char *exp){ SeqStack myStack;//對操作符進行中綴到字尾 StackInitiate(&myStack); double num[100];//儲存運算元 注:在彈出操作符的以後要立刻取出num最後面兩個數字進行運算後存回num中 int numSize = 0; int i,j; int spot = 0; char c; for(i=0;i<strlen(exp);i++){ if((exp[i]=='0'||exp[i]=='1'||exp[i]=='2'||exp[i]=='3'||exp[i]=='4'||exp[i]=='5'||exp[i]=='6'||exp[i]=='7'||exp[i]=='8'||exp[i]=='9')&&spot==0){ j=i+1; while(exp[j]=='0'||exp[j]=='1'||exp[j]=='2'||exp[j]=='3'||exp[j]=='4'||exp[j]=='5'||exp[j]=='6'||exp[j]=='7'||exp[j]=='8'||exp[j]=='9'){ j++; } num[numSize] = num[numSize] + (exp[i]-'0') * pow(10,j-i-1); if(j-i-1==0&&exp[j]!='.'){ numSize++; } continue; } if(exp[i]=='.'||spot==1){ spot=1; if(exp[i]=='.'){ j=0; continue; }else{ j--; } num[numSize] = num[numSize] + (exp[i]-'0') * pow(10,j); if(exp[i+1]!='0'&&exp[i+1]!='1'&&exp[i+1]!='2'&&exp[i+1]!='3'&&exp[i+1]!='4'&&exp[i+1]!='5'&&exp[i+1]!='6'&&exp[i+1]!='7'&&exp[i+1]!='8'&&exp[i+1]!='9'){ numSize++; spot=0; } } if(exp[i]=='+'){ if(!StackNotEmpty(myStack)){ StackPush(&myStack,exp[i]); }else if(StackTop(myStack,&c)&&(c=='*'||c=='/'||c=='-'||c=='+')){ while(StackTop(myStack,&c)&&(c=='*'||c=='/'||c=='-'||c=='+')){ StackPop(&myStack,&c); switch(c){ case '*':num[numSize-2] = num[numSize-2]*num[numSize-1]; numSize--; num[numSize]=0; break; case '/':num[numSize-2] = num[numSize-2]/num[numSize-1]; numSize--; num[numSize]=0; break; case '-':num[numSize-2] = num[numSize-2]-num[numSize-1]; numSize--; num[numSize]=0; break; case '+':num[numSize-2] = num[numSize-2]+num[numSize-1]; numSize--; num[numSize]=0; break; } if(!StackNotEmpty(myStack)){ break; } } StackPush(&myStack,exp[i]); }else if(StackTop(myStack,&c)&&c=='('){ StackPush(&myStack,exp[i]); } } if(exp[i]=='-'){ if(exp[i-1]!='0'&&exp[i-1]!='1'&&exp[i-1]!='2'&&exp[i-1]!='3'&&exp[i-1]!='4'&&exp[i-1]!='5'&&exp[i-1]!='6'&&exp[i-1]!='7'&&exp[i-1]!='8'&&exp[i-1]!='9'&&exp[i-1]!='('&&exp[i-1]!=')'){ printf("輸入格式錯誤!Tip:負數請加括號如(-1)\n"); break; } if(!StackNotEmpty(myStack)){ StackPush(&myStack,exp[i]); }else if(StackTop(myStack,&c)&&(c=='*'||c=='/'||c=='+'||c=='-')){ while(StackTop(myStack,&c)&&(c=='*'||c=='/'||c=='+'||c=='-')){ StackPop(&myStack,&c); switch(c){ case '*':num[numSize-2] = num[numSize-2]*num[numSize-1]; numSize--; num[numSize]=0; break; case '/':num[numSize-2] = num[numSize-2]/num[numSize-1]; numSize--; num[numSize]=0; break; case '+':num[numSize-2] = num[numSize-2]+num[numSize-1]; numSize--; num[numSize]=0; break; case '-':num[numSize-2] = num[numSize-2]-num[numSize-1]; numSize--; num[numSize]=0; break; } if(!StackNotEmpty(myStack)){ break; } } StackPush(&myStack,exp[i]); }else if(StackTop(myStack,&c)&&(c=='('||c==')')){ StackPush(&myStack,exp[i]); } } if(exp[i]=='*'){ if(!StackNotEmpty(myStack)||(StackTop(myStack,&c)&&(c=='+'||c=='-'))){ StackPush(&myStack,exp[i]); }else if(StackTop(myStack,&c)&&(c=='/')){ StackPop(&myStack,&c); switch(c){ case '/':num[numSize-2] = num[numSize-2]/num[numSize-1]; numSize--; num[numSize]=0; break; } StackPush(&myStack,exp[i]); }else if(StackTop(myStack,&c)&&(c=='('||c==')')){ StackPush(&myStack,exp[i]); } } if(exp[i]=='/'){ if(!StackNotEmpty(myStack)||(StackTop(myStack,&c)&&(c=='+'||c=='-'))){ StackPush(&myStack,exp[i]); }else if(StackTop(myStack,&c)&&(c=='*')){ StackPop(&myStack,&c); switch(c){ case '*':num[numSize-2] = num[numSize-2]*num[numSize-1]; numSize--; num[numSize]=0; break; } StackPush(&myStack,exp[i]); }else if(StackTop(myStack,&c)&&(c=='('||c==')')){ StackPush(&myStack,exp[i]); } } if(exp[i]=='('){ StackPush(&myStack,exp[i]); if(exp[i+1]=='-'){ int k=strlen(exp); while(k-1>i){ exp[k]=exp[k-1]; k--; } exp[i+1]='0'; } } if(exp[i]==')'){ while(StackTop(myStack,&c)&&c!='('){ StackPop(&myStack,&c); switch(c){ case '*':num[numSize-2] = num[numSize-2]*num[numSize-1]; numSize--; num[numSize]=0; break; case '/':num[numSize-2] = num[numSize-2]/num[numSize-1]; numSize--; num[numSize]=0; break; case '+':num[numSize-2] = num[numSize-2]+num[numSize-1]; numSize--; num[numSize]=0; break; case '-':num[numSize-2] = num[numSize-2]-num[numSize-1]; numSize--; num[numSize]=0; break; } } StackPop(&myStack,&c); } } while(StackNotEmpty(myStack)){ StackPop(&myStack,&c); switch(c){ case '*':num[numSize-2] = num[numSize-2]*num[numSize-1]; numSize--; num[numSize]=0; break; case '/':num[numSize-2] = num[numSize-2]/num[numSize-1]; numSize--; num[numSize]=0; break; case '+':num[numSize-2] = num[numSize-2]+num[numSize-1]; numSize--; num[numSize]=0; break; case '-':num[numSize-2] = num[numSize-2]-num[numSize-1]; numSize--; num[numSize]=0; break; } } return num[0];//最後的值 }
5.測試的主函式
void main(void){
char exp[200]="";
printf("請輸入一個表示式\t形如:2+3+(-5)+1.2\n");
scanf("%s",exp);
printf("\n結果為:%lf",expressionComputation(exp));
}
6.測試結果
可能會存在其他意想不到的錯誤,若測試出現其他錯誤請指正,我會加以修正。