题目描述
输入一个表达式(用字符串表示),求这个表达式的值。
保证字符串中的有效字符包括[‘0’-‘9’],‘+’,‘-’, ‘*’,‘/’ ,‘(’, ‘)’,‘[’, ‘]’,‘{’ ,‘}’。且表达式一定合法。
输入描述:
输入一个算术表达式
输出描述:
得到计算结果
示例1
输入
3+2*{1+2*[-4/(8-6)+7]}输出
25
利用两个stack,一个存储计算结果的值,一个存储符号,留意的地方是计算结果的值需要考虑正负号
#include <iostream>
#include <stack>
#include <cstring>
using namespace std;
//将所有的括号转换为()
void convertStr(string& str){
for(int i=0;i<str.size();i++){
if(str[i]=='['||str[i]=='{'){
str[i]='(';
}else if(str[i]==']'||str[i]=='}'){
str[i]=')';
}
}
}
int operation(int v1,int v2,char operate){
int res=0;
switch(operate){
case '+':res=v1+v2;break;
case '-':res=v1-v2;break;
case '*':res=v1*v2;break;
case '/':res=v1/v2;break;
}
return res;
}
int computing(string& str){
int flag=0;//标记正负号,0表示无符号,1表示正号,2表示负号
stack<int> nums;
stack<char> operas;
for(int i=0;i<str.size();i++){
if(isdigit(str[i])){
int j=i;
while(i+1<str.size()&&isdigit(str[i+1])) ++i;
string str_num=str.substr(j,i-j+1);
int num=stoi(str_num);//转换为数字
if(flag==2) num=0-num;
flag=0;//使用完毕数字的正负号归0
nums.push(num);
}else if(str[i]=='*'||str[i]=='/'||str[i]=='('){
operas.push(str[i]);//直接入栈
}else if(str[i]=='+'||str[i]=='-'){
if(i==0||str[i-1]=='('){//先判断是不是数字的正负号
if(str[i]=='+') flag=1;
else flag=2;
}
//遇到加减号,先进行计算
while(flag==0&&!operas.empty()&&operas.top()!='('){
//非空,符号弹出
int v1=nums.top();nums.pop();
int v2=nums.top();nums.pop();
char opera=operas.top();operas.pop();
nums.push(operation(v2,v1,opera));
}
if(flag==0) operas.push(str[i]);//证明通过operation得到的
}else if(str[i]==')'){
while(operas.top()!='('){
int v1=nums.top();nums.pop();
int v2=nums.top();nums.pop();
char opera=operas.top();operas.pop();
nums.push(operation(v2,v1,opera));
}
operas.pop();//弹出左括号
}
}
//最后计算栈中的数字
while(!operas.empty()){
//非空,符号弹出
int v1=nums.top();nums.pop();
int v2=nums.top();nums.pop();
char opera=operas.top();operas.pop();
nums.push(operation(v2,v1,opera));
}
return nums.top();
}
int main(int argc,char* argv[]){
string str;
while(cin>>str){
convertStr(str);
cout<<computing(str)<<endl;
}
return 0;
}