知识点:栈
难度:3
括号序列和表达式计算类型的题目,天然可以用栈来解决,这个需要自己好好消化,并且栈和二叉树关系密切,因为二叉树的深度优先遍历是用递归来实现的,而递归的机器基础又是栈,所以二叉树和栈之间存在紧密练习,这个还要以后多做题好好感受一下,
回到这个题,李煜东已经很详细的讲解了中缀表达式转化成后缀表达式的方法,但是没有带乘方这个运算符,那么这里就加上,题目的下面也有提示,别的同级的运算符之间都是从左向右结合,但是乘方是从右向左结合,所以其它的都不变,但是我们遍历到乘方这个运算符的时候直接入符号栈,不需要把前面的优先级大于等于它的(实际上前面只可能有等于它优先级的不可能有大于它优先级的)出栈,这是我试出来的,应该也是乘方是从右向左结合的体现,只有这个点是不一样的,其它的都一样
#include <bits/stdc++.h>
using namespace std;
int main() {
string s;
cin >> s;
stack<char> st;
string ss;
for (int i = 0; i < (int) s.size(); i++) {
if (isdigit(s[i])) ss += s[i];
else if (s[i] == '(') st.push(s[i]);
else if (s[i] == ')') {
while (st.top() != '(') {
ss += st.top();
st.pop();
}
st.pop();
} else {
if (s[i] == '*' || s[i] == '/') {
while (!st.empty()) {
char t = st.top();
if (t == '^' || t == '*' || t == '/') { ss += t; st.pop(); }
else break;
}
} else if (s[i] == '+' || s[i] == '-') {
while (!st.empty()) {
char t = st.top();
if (t != '(') { ss += t; st.pop(); }
else break;
}
}
st.push(s[i]);
}
}
while (!st.empty()) {
ss += st.top();
st.pop();
}
deque<int> q;
for (int i = 0; i < (int) ss.size(); i++) {
if (isdigit(ss[i])) q.push_back(ss[i] - '0');
else {
int len = (int) q.size();
for (int j = 0; j < len; j++) {
cout << q.front() << ' ';
q.push_back(q.front());
q.pop_front();
}
for (int j = i; j < (int) ss.size(); j++) {
cout << ss[j] << (j < (int) ss.size() - 1 ? ' ' : '\n');
}
int x = q.back(); q.pop_back();
int y = q.back(); q.pop_back();
if (ss[i] == '+') q.push_back(x + y);
if (ss[i] == '-') q.push_back(y - x);
if (ss[i] == '*') q.push_back(x * y);
if (ss[i] == '/') q.push_back(y / x);
if (ss[i] == '^') q.push_back((int) pow(y, x));
}
}
cout << q.front();
return 0;
}