暑期训练3 Gym - 102309A APA of Orz Pandas 栈,逆波兰表达式,模拟
暑期训练3 Gym - 102309A APA of Orz Pandas 栈,逆波兰表达式,模拟
题意
给出一个包含乘,除,加,减,取余的中缀表达式,要求转化为JAVA的大整数的运算模式,且运算元素的顺序要求严格相等。例如
Input
\[a + b + c
\\
(a+b)+c
\\
a+(b+c)
\\
(a+b)\%(c+d)
\]
Output
\[a.add(b).add(c)
\\
a.add(b).add(c);
\\
a.add(b.add(c))
\\
a.add(b).remainder(c.add(d))
\]
The length of the expressions will not exceed 1000.
分析
考虑到难点主要在于括号,而逆波兰表达式正好可以很好的解决问题,因此这道题的思路就是转化为逆波兰表达式再把相应的加法改成"add"....
中缀表达式转逆波兰表达式
-
建立一个用于存放运算符的栈,逐一扫描该中缀表达式中的元素
-
如果遇到一个数,输出该数
-
如果遇到左括号,把左括号入栈
-
如果遇到右括号,不断取出栈顶并输出,直到栈顶为左括号,然后把左括号出栈
-
如果遇到运算符,只要栈顶符号优先级不低于新符号,就不断取出栈顶并输出 ,最后把新符号入栈。
-
-
依次取出并输出栈中所有的剩余符号
逆波兰表达式求值
- 建立一个用于存数的栈,逐一扫描该后缀表达式中的元素
- 如果遇到一个数,则把这个数入栈
- 如果遇到运算符,就取出栈顶的两个数进行计算,把结果入栈
- 扫描完成后,栈中只剩下一个数,就是逆波兰表达式的值
注意此题的运算数是字母,且可能是多个字母
代码
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
string ss;
vector<string> res;
stack<string> st;
stack<string> ans;
while (cin >> ss) {
while (!st.empty()) st.pop();
while (!ans.empty()) ans.pop();
res.clear();
for (int i = 0; i < ss.length(); i++) {
if ((ss[i] >= 'a' && ss[i] <= 'z') || (ss[i] >= 'A' && ss[i] <= 'Z')) {
string tmp = "";
while ((ss[i] >= 'a' && ss[i] <= 'z') || (ss[i] >= 'A' && ss[i] <= 'Z')) tmp.push_back(ss[i++]);
i--;
res.push_back(tmp);
}
else if (ss[i] == '(') {
string tmp = "(";
st.push(tmp);
}
else if (ss[i] == ')') {
while (st.top() != "(") res.push_back(st.top()), st.pop();
st.pop();
}
else {
string tmp = "";
tmp.push_back(ss[i]);
if (ss[i] == '*' || ss[i] == '/' || ss[i] == '%') while (!st.empty() && (st.top() == "*" || st.top() == "/" || st.top() == "%")) res.push_back(st.top()), st.pop();
else if (ss[i] == '+' || ss[i] == '-') while (!st.empty() && (st.top() != "(")) res.push_back(st.top()), st.pop();
st.push(tmp);
}
}
while (!st.empty()) res.push_back(st.top()), st.pop();
for (int i = 0; i < res.size(); i++) {
if (res[i] != "*" && res[i] != "/" && res[i] != "+" && res[i] != "-" && res[i] != "%") {
ans.push(res[i]);
}
else {
string a1 = ans.top(); ans.pop();
string a2 = ans.top(); ans.pop();
string tmp = "";
tmp += a2;
if (res[i] == "+") tmp += ".add(";
else if (res[i] == "-") tmp += ".substract(";
else if (res[i] == "*") tmp += ".multiply(";
else if (res[i] == "/") tmp += ".divide(";
else if (res[i] == "%") tmp += ".remainder(";
tmp += a1;
tmp += ')';
ans.push(tmp);
}
}
cout << ans.top() << '\n';
}
}