中綴表示式轉後置表示式並求值(多位數完整版)
看了很多的中綴表示式轉換字尾表示式求值問題及程式碼,可是網路上的很多都是一位數的運算,我將程式碼進行了完善補充。 #include #include #include<math.h> #include #include #include using namespace std; //中綴轉字尾思路: //轉換過程需要用到棧,具體過程如下:
//1)如果遇到運算元,我們就直接將其輸出。
//2)如果遇到操作符,則我們將其放入到棧中,遇到左括號時我們也將其放入棧中。
//3)如果遇到一個右括號,則將棧元素彈出,將彈出的操作符輸出直到遇到左括號為止。注意,左括號只彈出並不輸出。
//4)如果遇到任何其他的操作符,如(“+”, “*”,“(”)等,從棧中彈出元素直到遇到發現更低優先順序的元素(或者棧為空)為止。彈出完這些元素後,才將遇到的操作符壓入到棧中。有一點需要注意,只有在遇到" ) “的情況下我們才彈出” ( “,其他情況我們都不會彈出” ( "。
//5)如果我們讀到了輸入的末尾,則將棧中所有元素依次彈出。
/從此處到註釋結束部份全部為一位數的運算,為了便於比較故放在前面 int judge(char a){//判斷運算子優先順序 switch(a){ case ‘+’: case ‘-’: return 1; case '’: case ‘/’: return 2; case ‘(’: return 3; case ‘)’: return -1; default: return 0; }
}
void calculate(char * s){//字尾表示式求值 stack result; int a,b; for(int i=0; s[i]; i++) { if(judge(s[i])==0){ result.push(s[i]-‘0’);
} else{ a=result.top(); result.pop(); // cout<<a<<" "; b=result.top(); // cout<<b<<endl; result.pop(); if(s[i]=='+') result.push(b+a); if(s[i]=='-') result.push(b-a); if(s[i]=='*') result.push(a*b); if(s[i]=='/') result.push(b/a); } } cout<<result.top();
}
void transmit(char *s, char *save){
int count=0;
stack<char> result;
for(int i=0; s[i]; i++){
if(judge(s[i])==0){
//cout<<s[i]<<" ";//遇到數字就直接輸出
save[count++]=s[i];
}
if(judge(s[i])>0){//遇到操作符就根據情況壓棧彈棧
if(result.empty())//棧為空則直接壓棧
result.push(s[i]);
else{//棧不為空
if(judge(s[i])>judge(result.top()))//操作符優先順序比棧頂操作符優先順序高
result.push(s[i]);
else{ //彈棧並輸出直到棧為空或遇到優先順序更低的操作符 (除了左括號)
while((!result.empty())&&judge(result.top())>=judge(s[i])&&result.top()!='(')
{
save[count++]=result.top();
result.pop();
}
result.push(s[i]);
}
}
}
if(judge(s[i])==-1){
while(result.top()!='('){
save[count++]=result.top();
//cout<<result.top()<<" ";
result.pop();
}
result.pop();
}
}
while(!result.empty()){
//cout<<result.top()<<" ";
save[count++]=result.top();
result.pop();
}
int num=0;
for(int i=0;save[i];i++)
num++;
for(int i=0; i<num-1; i++)
cout<<save[i]<<" ";
cout<<save[num-1]<<endl;
calculate(save);
}
/ //此處開始為多位數的運算 int judge(string a){ if(a=="+"||a=="-") return 1; else if(a==""||a=="/") return 2; else if(a=="(") return 3; else if(a==")") return -1; else return 0; }
int sti(string a){ stringstream ss; int s; ss<<a; ss>>s; return s; }
void calculate(vector s){ stack result; int a,b; for(int i=0; i<s.size();i++){
if(judge(s[i])==0)
result.push(sti(s[i]));
else{
a=result.top();
result.pop();
b=result.top();
result.pop();
if(s[i]=="+")
result.push(b+a);
if(s[i]=="-")
result.push(b-a);
if(s[i]=="*")
result.push(a*b);
if(s[i]=="/")
result.push(b/a);
}
}
cout<<result.top();
}
void transmit(vector s, vector save){ stack result; //for(int i=0;i<s.size();i++) // cout<<s[i]<<endl; for(int i=0; i<s.size();i++){
if(judge(s[i])==0)//遇到數字就直接輸出
save.push_back(s[i]);
if(judge(s[i])>0){
if(result.empty())//棧為空則直接壓棧
result.push(s[i]);
else{
if(judge(s[i])>judge(result.top()))//操作符優先順序比棧頂操作符優先順序高
{ result.push(s[i]);
//cout<<s[i];
}
else{
while((!result.empty())&&judge(result.top())>=judge(s[i])&&result.top()!="(")//彈棧並輸出直到棧為空或遇到優先順序更低的操作符 (除了左括號)
{
save.push_back(result.top());
result.pop();
}
result.push(s[i]);
}
}
}
if(judge(s[i])==-1){
while(result.top()!="("){
save.push_back(result.top());
//cout<<result.top()<<" ";
result.pop();
}
result.pop();
}
}
while(!result.empty()){
//cout<<result.top()<<" ";
save.push_back(result.top());
result.pop();
}
for(int i=0; i<save.size(); i++)
cout<<save[i]<<" ";
cout<<endl;
calculate(save);
}
void stv(vectora, string s){ int j,i; i=0; while(i<s.size()) { j=i;
while(j<s.size()&&s.at(j)<='9'&&s.at(j)>='0'){
j++;
}
if(i==j){
a.push_back(s.substr(i,1));
i=i+1;
}
else{
a.push_back(s.substr(i,j-i));
i=j;
}
}
vector<string> save;
transmit(a,save);
}
int main(){
string str1;
cin>>str1;
vector<string>a;
vector<string>b;
//transmit(a,b);
stv(b,str1);
}// 測試樣例 15+8/2+8/(6-2*1) 15 8 2 / + 8 6 2 1 * - / + 21