描述
输入一个表达式(用字符串表示),求这个表达式的值。
保证字符串中的有效字符包括[‘0’-‘9’],‘+’,‘-’, ‘*’,‘/’ ,‘(’, ‘)’,‘[’, ‘]’,‘{’ ,‘}’。且表达式一定合法。
数据范围:表达式计算结果和过程中满足 ∣val∣≤1000 ,字符串长度满足 1≤n≤1000
输入描述:
输入一个算术表达式
输出描述:
得到计算结果
示例1
输入:
3+2*{1+2*[-4/(8-6)+7]}
输出:
25
#include<cstdio>
#include<stack>
#include<string>
#include<map>
using namespace std;
stack<double> num_stack;
stack<char> op_stack;
map<char,int> prio={
{'$',0},
{'+',2},{'-',2},
{'*',3},{'/',3},
};
double cal(double left,double right,char op)
{
double res;
switch (op) {
case '+': res=left + right; break;
case '-': res=left - right; break;
case '*': res=left * right; break;
case '/': res=left / right; break;
}
return res;
}
int main()
{
// 0.读取数据及预处理
char buf[2000];
fgets(buf,2000,stdin);
string str=buf;
str.pop_back();
str.push_back('$');//补充一个终止符
/*
1.字符串预处理
1)对表示正负数的加减号进行处理,在其前面加数字0
2)[]、{}统一用()代替
*/
string new_str="";
for(int i=0;i<str.size();i++)
{
/*
加减号出现的位置:第一个字符 或 紧跟左括号之后
*/
if(i==0 && str[i]=='+' || i==0 && str[i]=='-')
{
new_str.push_back('0');
}
else
{
if((str[i]=='+' && str[i-1]=='{') || (str[i]=='+' && str[i-1]=='(') || (str[i]=='+' && str[i-1]=='['))
{
new_str.push_back('0');
}
if((str[i]=='-' && str[i-1]=='{') || (str[i]=='-' && str[i-1]=='(') || (str[i]=='-' && str[i-1]=='['))
{
new_str.push_back('0');
}
if(str[i]=='{' || str[i]=='[')
{
str[i]='(';
}
if(str[i]=='}' || str[i]==']')
{
str[i]=')';
}
}
new_str.push_back(str[i]);
}
// 2.计算过程
string num="";//用于收集操作数
for(int i=0;i<new_str.size();i++)
{
// 2.1 遇到数字
if(new_str[i]>='0' && new_str[i]<='9')
{
num.push_back(new_str[i]);
}
// 2.2 非数字
else {
if(num!="")
{
// 数字进栈
num_stack.push(stod(num));
num="";
}
// 1)遇到左括号,左括号进栈
if(new_str[i]=='(')
{
op_stack.push(new_str[i]);
}
// 2)遇到运算符、右括号
else{
// 1-1)遇到右括号计算
if(new_str[i]==')')
{
while (op_stack.top()!='(' && op_stack.empty()==false) {
// 取出两个操作数
double right=num_stack.top();
num_stack.pop();
double left=num_stack.top();
num_stack.pop();
// 取出一个运算符
char op=op_stack.top();
op_stack.pop();
// 计算结果并压入栈
double res=cal(left,right,op);
num_stack.push(res);
}
// 左括号出栈
op_stack.pop();
}
// 1-2)遇到运算符
else {
while (op_stack.empty()==false && prio[new_str[i]] <= prio[op_stack.top()] && op_stack.top()!='(') {
// 取出两个操作数
double right=num_stack.top();
num_stack.pop();
double left=num_stack.top();
num_stack.pop();
// 取出一个运算符
char op=op_stack.top();
op_stack.pop();
// 计算结果并压入栈
double res=cal(left,right,op);
num_stack.push(res);
}
// 运算符进栈
op_stack.push(new_str[i]);
}
}
}
}
// 3.输出结果
printf("%d",(int)num_stack.top());
}