給出一個表達式,求取表達式的值
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <stack>
using namespace std;
/***
思路:
1.字符串預處理,針對可能出現的“{,},[,],-”等特殊情況進行替換,判斷‘-’是負號還是減號,負號前面+0,轉變成減法運算
2.將中綴字符串轉變爲後綴字符串數組
3.對後綴字符串數組進行求解
***/
int main(int argc, char const *argv[])
{
string str;
while(getline(cin,str))
calcExp(str);
return 0;
}
void calcExp(string &str){
preProcess(str);
vector<string>vstr=mid2post(str);
double res=calcPostExp(vstr);
cout<<res<<endl;
}
/***
對字符串進行預處理:
1.將‘{、}、[,]’替換成'()'
2.將'-'前面添加0轉變成減法運算
***/
void preProcess(string &str){
int num=str.size();
for(int i=0;i<num;i++){
if(str[i]=='{')
str[i]='(';
else if (str[i]=='}')
str[i]=')';
else if(str[i]=='[')
str[i]='(';
else if(str[i]==']')
str[i]=')';
else if(str[i]=='-'){
if(i==0)
str.insert(0,1,'0');
else if(str[i-1]=='(')
str.insert(i,1,'0');
}
}
}
//中綴轉後綴
vector<string>& mid2post(string &str){
vector<string>vstr;
satck<char>cstack;
string temp="";
//掃描字符串
for(int i=0,n=str.size();i<n;i++){
temp="";
//若爲數字
if(str[i]>='0'&&str[i]<='9'){
temp+=str[i];
while(i+1<n&&str[i+1]>='0'&&str[i+1]<='9'){
temp+=str[i+1];
i++;
}
vstr.push_back(temp);
}
//棧空或遇見字符'('
else if(cstack.empty()||str[i]=='(')
cstack.push(str[i]);
//若棧頂優先級高
else if(cmpPriority(cstack.top(),str[i])){
//當前字符爲')',棧中元素出棧,入字符串數組中,直到遇到'('
if(str[i]==')'){
while(!cstack.empty()&&cstack.top()!='('){
temp+=cstack.top();
cstack.pop();
vstr.push_back(temp);
temp=""
}
cstack.pop();
}
//棧中優先級高的元素出棧,入字符串數組,直到優先級低於當前字符
else{
while(!cstack.empty()&&cmpPriority(cstack.top(),str[i])){
temp+=cstack.top();
cstack.pop();
vstr.push_back(temp);
temp="";
}
cstack.push(str[i]);
}
}
//當前字符優先級高於棧頂元素,直接入棧
else
cstack.push(str[i]);
}
//棧中還存在運算符時:出棧,存入字符串數組
while(!cstack.empty){
temp+=cstack.top();
cstack.pop();
vstr.push_back(temp);
temp="";
}
return vstr;
}
//比較當前字符與棧頂字符的優先級,若棧頂高,返回true
bool cmpPriority(char top,char cur){
if((top=='+'||top=='-')&&(cur=='+'||cur=='-'))
return true;
if((top=='*'||top=='/')&&(cur=='+' || cur=='-'|| cur=='*' || cur=='/'))
return true;
if(cur==')')
return true;
return false;
}
//對後綴表達式進行求值:主要是根據運算符取出兩個操作數進行運算
double calcPostExp(vector<string>&vstr){
stack<double>opstack;
int num,op1,op2;
string temp="";
stringstream ss;
for(int i=0,n=vstr.size();i<n;i++){
temp=vstr[i];
//如果當前字符串是數字,利用字符串流轉化爲int型
if(temp[0]>='0'&&temp[0]<='9'){
ss<<temp;//通過流將數值轉爲字符串,或將字符串轉爲數值。
ss>>num;
opstack.push(num);
}
//若是操作符,取出兩個操作數,進行運算,並將結果存入
else if(vstr[i]=='+'){
op2=opstack.top();
opstack.pop();
op1=opstack.top();
opstack.pop();
opstack.push(op1+op2);
}
else if(vstr[i]=='-'){
op2=opstack.top();
opstack.pop();
op1=opstack.top();
opstack.pop();
opstack.push(op1-op2);
}
else if(vstr[i]=='*'){
op2=opstack.top();
opstack.pop();
op1=opstack.top();
opstack.pop();
opstack.push(op1*op2);
}
else if(vstr[i]=='/'){
op2=opstack.top();
opstack.pop();
op1=opstack.top();
opstack.pop();
opstack.push(op1+op2);
}
}
return opstack.top();
}