问题描述
输入一个只包含加减乖除和括号的合法表达式,求表达式的值。其中除表示整除。
输入格式
输入一行,包含一个表达式。
输出格式
输出这个表达式的值。
样例输入
1-2+3*(4-5)
样例输出
-4
数据规模和约定
表达式长度不超过100,表达式运算合法且运算过程都在int内进行。
解题思路:在这篇文章简易表达式计算(点这里)中是对不含括号的表达式进行计算,这里就讲述对于括号的处理。唯一不同是在转化为后缀表达式中,在遇到’(‘时直接压栈,在遇到’)‘时将栈中元素出栈装入队列中知道遇到’)‘然后将’)'也出栈,注意这里的左右括号都是不装入队列中的。对于后缀表达式的计算即注意事项在上一篇文章都有介绍
代码:
#include<cstdio>
#include<stack>
#include<queue>
#include<string>
#include<map>
#include<iostream>
using namespace std;
struct node {
int num;
char op;
int flag;
};
stack<node> st;
queue<node> q;
map<char, int> mp;
void to_back(string s) { //中缀转后缀
node node,oper;
for (int i = 0; i < s.size(); i++) {
int num = 0;
if (s[i] >= '0' && s[i] <= '9') { //数字可能不止一位
num = s[i] - '0';
while (s[i + 1] >= '0' && s[i + 1] <= '9') {
num = num * 10 + s[i+1] - '0';
i++;
}
node.num = num;
node.flag = 1;
q.push(node);
}
else {
oper.op = s[i];
if (st.empty()) //栈空直接将运算符压栈
st.push(oper);
else {
char temp = st.top().op;
if (s[i] == ')') { //运算符为')' 则将栈顶元素出栈知道遇到'('
while (st.top().op != '(') {
oper = st.top();
st.pop();
q.push(oper);
}
st.pop(); //这里将'('出栈
}
else if (s[i] == '(' || mp[s[i]] > mp[temp]) { //栈顶为'('或者当前运算符优先级大于栈顶元素优先级则压栈
st.push(oper);
}
else {
while (!st.empty() && mp[s[i]] <= mp[st.top().op]) { //当前运算符优先级不大于栈顶元素优先级
oper = st.top(); //将栈顶元素出栈直到栈顶元素优先级小于当前元素优先级
st.pop();
q.push(oper);
}
oper.op = s[i];
st.push(oper);
}
}
}
}
while (!st.empty()) { //最后将栈中元素出栈
oper = st.top();
st.pop();
q.push(oper);
}
}
void cul() { //计算后缀表达式
node Node;
while (!q.empty()) {
node front = q.front();
if (front.flag == 1) { //是数字入栈
q.pop();
st.push(front);
}
else { //是运算符则从栈中弹出两个数字
int num2 = st.top().num; //先弹出的是第二运算数
st.pop();
int num1 = st.top().num;
st.pop();
if (front.op == '+')
Node.num = num1 + num2;
else if (front.op == '-')
Node.num = num1 - num2;
else if (front.op == '*')
Node.num = num1 * num2;
else
Node.num = num1 / num2;
Node.flag = 1; //将计算后的数压栈
st.push(Node);
q.pop();
}
}
}
int main(void) {
mp['+'] = mp['-'] = 1;
mp['*'] = mp['/'] = 2;
string s;
cin >> s;
to_back(s);
while (!st.empty()) {
st.pop();
}
cul();
printf("%d", st.top().num);
return 0;
}