演算法練習——表示式計算
阿新 • • 發佈:2019-01-30
問題描述
輸入一個只包含加減乖除和括號的合法表示式,求表示式的值。其中除表示整除。
輸入格式
輸入一行,包含一個表示式。
輸出格式
輸出這個表示式的值。
樣例輸入
1-2+3*(4-5)
樣例輸出
-4
資料規模和約定
表示式長度不超過100,表示式運算合法且運算過程都在int內進行。
C++程式碼如下:
#include<iostream> #include<cstring> #include<stack> #include<algorithm> #include<cmath> using namespace std; stack<char> s1,s2; stack<int> s3; char ch[150]={0};//用來存表示式 int num[11];//用來暫時存數字 int priority(char ch)//用於比較字元優先順序 { if(ch==')') return 1; if(ch=='+'||ch=='-') return 2; if(ch=='*'||ch=='/') return 3; if(ch=='(') return 4; } int Scal(int x,int y,char ope)//兩個數的運算 { if(ope=='+') return x+y; if(ope=='-') return x-y; if(ope=='*') return x*y; if(ope=='/'&&y!=0) return x/y; } void Transform(int n)//將中綴表示式轉化為字尾表示式 { int k=0; for(int i=0;i<n;i++) { if(ch[i]>='0'&&ch[i]<='9')//當是數字的情況 { if(i+1<n&&(ch[i+1]<'0'||ch[i+1]>'9')||i==n-1)//當是最後一個數字,或下一個元素是運算子 { s2.push(ch[i]); s2.push('#'); } else s2.push(ch[i]); } else { if(s1.empty()||ch[i]=='('||priority(ch[i])>priority(s1.top()))//當是運算子,有3種情況直接入棧 s1.push(ch[i]); else if(ch[i]==')')//當是右括號的情況 { while(s1.top()!='(') { s2.push(s1.top()); s1.pop(); } s1.pop(); } else//當運算子優先順序小於或等於S1棧頂運算子的優先順序 { while(!s1.empty()&&priority(ch[i])<=priority(s1.top())&&s1.top()!='(')//這裡還要注意兩個界限 { s2.push(s1.top()); s1.pop(); } s1.push(ch[i]); } } } while(!s1.empty())//當表示式結束 { s2.push(s1.top()); s1.pop(); } while(!s2.empty()) //將棧內元素放回S2中 { ch[k++]=s2.top(); s2.pop(); } reverse(ch,ch+k);//將ch[]反向 ch[k]=0; } int Cal(int n)//字尾表示式計算 { int x,y,tmp=0,k=0; for(int i=0;i<n;i++) { if(ch[i]=='#')//是#直接跳過 continue; else if(ch[i]=='+'||ch[i]=='-'||ch[i]=='*'||ch[i]=='/')//是運算子彈出棧頂兩元素計算後放回棧 { x=s3.top(); s3.pop(); y=s3.top(); s3.pop(); x=Scal(y,x,ch[i]); s3.push(x); } else//是數字字元 { if(ch[i+1]=='#')//下一個元素是# { num[k++]=ch[i]-'0'; for(int i=0;i<k;i++) tmp+=(num[i]*(int)pow(10,k-i-1)); s3.push(tmp); tmp=0; k=0; } else//下一個元素不是# { num[k++]=ch[i]-'0'; } } } return s3.top(); } int main() { gets(ch); Transform(strlen(ch)); cout<<Cal(strlen(ch))<<endl; return 0; }