给出一个表达式,求取表达式的值
#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();
}