18
#include<stack>#include<stdio.h>using namespace std;char str[220];//儲存運算式字串 int mat[][5]={//優先順序矩陣,mat[i][j]=1,代表i號運算子優先順序大於j號運算子 1,0,0,0,0, 1,0,0,0,0, 1,0,0,0,0, 1,1,1,0,0, 1,1,1,0,0,}; stack<int>op;//運算子棧stack<double>in;//數字棧void getOp(bool &reto,int&retn,int&i){ //獲得運算式中下一個元素,若函數運行結束時,引用變數reto為true,則表示該元素為一個運算子,其編號儲存在retn中; //否則,表示該元素為一個數字,其值儲存在retn中。引用變數i表示遍曆到的字串下標 if(i==0&&op.empty()==true)//若此時遍曆字串第一個字元,且運算子棧為空白,我們人為委任標記為0的標記字元 { reto=true;//為運算子, retn=0;//編號為0 return; } if(str[i]==‘\0‘){//若此時遍曆字元為空白字元,則表示字串已經被遍曆完 reto=true;//返回為運算子 retn=0;//編號為0 return; } if(str[i]>=‘0‘&&str[i]<=‘9‘)//若當前字元為數字 { reto=false;//返回為數字 } else{ reto=true;//返回為運算子 if(str[i]==‘+‘){ retn=1; } else if(str[i]==‘-‘){ retn=2; } else if(str[i]==‘*‘){ retn=3; } else if(str[i]==‘/‘){ retn=4; } i+=1;//i遞增,跳過該運算子和該運算字元後的空格 return; } retn=0;//返回結果為數字 for(;str[i]>=‘0‘&&str[i]<=‘9‘&&str[i]!=0;i++) { retn*=10; retn+=str[i]-‘0‘; }//計算該數位值 //if(str[i]==‘ ‘)//若其後字元為空白格,則表示字串未被遍曆完 //{ // ++i;//i遞增,跳過該空格 //} return; } int main(){ while(scanf("%s",str)!=EOF) { bool retop;int retnum;//定義函數所需的變數 int idx=0;//定義遍曆到的字串下標,初始值為0 while(!op.empty())op.pop(); while(!in.empty())in.pop();//清空數字棧和運算子棧 while(true)//迴圈遍曆運算式字串 { getOp(retop,retnum,idx);//擷取運算式中下一個元素 if(retop==false){//若該元素為數字 in.push((double)retnum);//將其壓入數字棧 } else{ double tmp; if(op.empty()==true||mat[retnum][op.top()]==1){//若運算子堆棧為空白或者遍曆到的運算子優先順序大於棧頂運算子,將該運算子壓入運算子堆棧 op.push(retnum); } else{ while(mat[retnum][op.top()]==0)//只要當前運算子優先順序小於棧頂元素運算子,則重複迴圈 { int ret=op.top();//儲存棧頂運算子 op.pop();//彈出 double b=in.top(); in.pop(); double a=in.top(); in.pop();//從數字堆棧棧頂彈出兩個數字,依次儲存在遍曆a,b中 if(ret==1)tmp=a+b; else if(ret==2)tmp=a-b; else if(ret==3)tmp=a*b; else tmp=a/b; in.push(tmp); } op.push(retnum);//將當前運算子壓入運算子堆棧 } } if(op.size()==2&&op.top()==0)break; } printf("%d\n",(int)in.top()); } return 0;}