用栈求表达式值
中缀表达式求值
原题链接
规则:
(1)遇到数字,则用第二个指针将该数字读取出来,然后push到nums中
(2)遇到(
,直接push
到ops
中
(3)遇到)
,则从ops
中逐一弹出操作符直到遇到(
,每弹出一个操作符,就通过count函数计算一遍该操作符计算出的值,再将该值压入栈
(4)遇到+
、-
、*
、/
,那么就通过while循环检查是否ops栈顶优先级大于等于当前操作符,若满足,则弹出栈顶操作符,计算值;最后将当前操作符压入ops
#include <bits/stdc++.h>
using namespace std;
string s;
stack<char> ops;
stack<int> nums;
void count(){
char op = ops.top();
ops.pop();
int b = nums.top();
nums.pop();
int a = nums.top();
nums.pop();
if(op == '+') nums.push(a + b);
else if(op == '-') nums.push(a - b);
else if(op == '*') nums.push(a * b);
else nums.push(a / b);
}
int main(){
cin >> s;
unordered_map<char, int> pr{{'+',1}, {'-',1}, {'*',2}, {'/',2}};
for(int i = 0; i < s.size(); ++i){
if(isdigit(s[i])){
int j = i, num = 0;
while(j < s.size() && isdigit(s[j])){
num += num * 10 + s[j] - '0';
++j;
}
nums.push(num);
i = j - 1;
}else if(s[i] == '('){
ops.push(s[i]);
}else if(s[i] == ')'){
while(!ops.empty() && ops.top() != '(') count();
if(ops.top() == '(') ops.pop();
}else{
while(!ops.empty() && ops.top() != '(' && pr[ops.top()] > pr[s[i]]) count();
ops.push(s[i]);
}
}
while(ops.size()) count();
printf("%d\n", nums.top());
return 0;
}
中缀表达式转后缀表达式
参考大佬博客的c++代码实现.
规则:
中缀表达式a + b*c + (d * e + f) * g
,其转换成后缀表达式则为a b c * + d e * f + g * +
。
转换过程需要用到栈,具体过程如下:
1)如果遇到操作数,我们就直接将其输出。
2)如果遇到操作符,则我们将其放入到栈中,遇到左括号时我们也将其放入栈中。
3)如果遇到一个右括号,则将栈元素弹出,将弹出的操作符输出直到遇到左括号为止。注意,左括号只弹出并不输出。
4)如果遇到任何其他的操作符,如(+
, *
,(
)等,从栈中弹出元素直到遇到发现更低优先级的元素(或者栈为空)为止。弹出完这些元素后,才将遇到的操作符压入到栈中。有一点需要注意,只有在遇到)
的情况下我们才弹出(
,其他情况我们都不会弹出(
。
5)如果我们读到了输入的末尾,则将栈中所有元素依次弹出。
#include<bits/stdc++.h>
using namespace std;
stack<char> ops;
string s;
int main(){
cin >> s;
unordered_map<char, int> pr{{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}};
for(int i = 0; i < s.size(); ++i){
if(isdigit(s[i])){
int j = i, x = 0;
while(j < s.size() && isdigit(s[j]))
x = x * 10 + s[j++] - '0';
cout << x;
i = j - 1;
}else if(s[i] == '(') ops.push(s[i]);
else if(s[i] == ')'){
while(ops.top() != '('){
cout << ops.top();
ops.pop();
}
ops.pop();
}else{
while(!ops.empty() && ops.top() != '(' && pr[ops.top()] >= pr[s[i]]){
cout << ops.top();
ops.pop();
}
ops.push(s[i]);
}
}
while(ops.size()){
cout << ops.top();
ops.pop();
}
return 0;
}