模板 - 表达式
一位数中缀表达式转后缀表达式并求后缀表达式值
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
//比较lhs的优先级是否不高于rhs,rhs表示栈顶的符号
bool priority(const char &lhs, const char &rhs) {
if (rhs == '(')//左括号在栈外优先级最高
return false;
if (lhs == '+' || lhs == '-')
return true;
if ((lhs == '*' || lhs == '/') && (rhs == '*' || rhs == '/'))
return true;
return false;
}
//将中缀表达式转换成后缀式(逆波兰表达式)
string exchange(const string &str) {
vector<char> vec;
string res;
stack<char> st;//操作符栈
for (int i = 0; i < str.size(); ++i) {
if (isdigit(str[i])) { //如果是数字,直接输出到后序表达式中
vec.push_back(str[i]);
} else { //如果是符号,需要与栈顶的元素进行比较
if (st.empty() || str[i] == '(')//小括号在栈外优先级最高,直接压栈
st.push(str[i]);
else {
if (str[i] == ')') { //遇到右括号,则弹栈,直到遇到左括号,两者相互抵消
while (st.top() != '(') {
vec.push_back(st.top());
st.pop();
}
st.pop();
} else {
//遇到的是其他操作符
//优先级比栈顶元素低
while (!st.empty()&&priority(str[i], st.top())) {
vec.push_back(st.top());
st.pop();
}
//优先级比栈顶元素高,压栈
st.push(str[i]);
}
}
}
}
while (!st.empty()) { //如果堆栈不为空,则将其中的元素全部弹出
vec.push_back(st.top());
st.pop();
}
for (auto v : vec)
res += v;
return res;
}
//定义四则运算
int operate(int first, int second, char op) {
int res = 0;
switch (op) {
case '+':
res = first + second;
break;
case '-':
res = first - second;
break;
case '*':
res = first * second;
break;
case '/':
res = first / second;
break;
default:
break;
}
return res;
}
int calculate(string input) {
stack<int> st;//操作数堆栈
for (auto &s : input) {
if (isdigit(s)) { //如果是数字就压栈
st.push(s - '0');
} else { //遇到字符就弹出两个操作数进行运算
int a = st.top();
st.pop();
int b = st.top();
st.pop();
st.push(operate(b, a, s));
}
}
return st.empty() ? 0 : st.top();//最后的结果为栈顶元素
}
int main() {
string str = "1+(3*4*5)/5+(4-8)*5-2/2+4";
cout << str << endl;
cout << exchange(str) << endl;
cout << calculate(exchange(str)) << endl;
return 0;
}
多位数中缀表达式转后缀表达式并求后缀表达式值,注意int可能溢出,不能求负数!
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
string prework(string s) {
string res="";
int n=s.length();
bool curnum=0;
for(int i=0; i<n; i++) {
if(isdigit(s[i])) {
curnum=1;
res+=s[i];
} else {
if(curnum==0) {
res+=s[i];
} else {
curnum=0;
res+='#';
res+=s[i];
}
}
}
if(curnum) {
curnum=0;
res+='#';
}
return res;
}
//比较lhs的优先级是否不高于rhs,rhs表示栈顶的符号
bool priority(const char &lhs, const char &rhs) {
if (rhs == '(')//左括号在栈外优先级最高
return false;
if (lhs == '+' || lhs == '-')
return true;
if ((lhs == '*' || lhs == '/') && (rhs == '*' || rhs == '/'))
return true;
return false;
}
//将中缀表达式转换成后缀式(逆波兰表达式)
string exchange(const string &str) {
vector<char> vec;
string res;
stack<char> st;//操作符栈
for (int i = 0; i < str.size(); ++i) {
if (isdigit(str[i])||str[i]=='#') { //如果是数字,直接输出到后序表达式中
vec.push_back(str[i]);
} else { //如果是符号,需要与栈顶的元素进行比较
if (st.empty() || str[i] == '(')//小括号在栈外优先级最高,直接压栈
st.push(str[i]);
else {
if (str[i] == ')') { //遇到右括号,则弹栈,直到遇到左括号,两者相互抵消
while (st.top() != '(') {
vec.push_back(st.top());
st.pop();
}
st.pop();
} else {
//遇到的是其他操作符
//优先级比栈顶元素低
while (!st.empty()&&priority(str[i], st.top())) {
vec.push_back(st.top());
st.pop();
}
//优先级比栈顶元素高,压栈
st.push(str[i]);
}
}
}
}
while (!st.empty()) { //如果堆栈不为空,则将其中的元素全部弹出
vec.push_back(st.top());
st.pop();
}
for (auto v : vec)
res += v;
return res;
}
//定义四则运算
int operate(int first, int second, char op) {
int res = 0;
switch (op) {
case '+':
res = first + second;
break;
case '-':
res = first - second;
break;
case '*':
res = first * second;
break;
case '/':
res = first / second;
break;
default:
break;
}
return res;
}
int calculate(string input) {
stack<int> st;//操作数堆栈
int cur=0;
for (auto s : input) {
if (isdigit(s)) { //如果是数字就压栈
cur=cur*10+(s - '0');
} else if(s=='#') {
st.push(cur);
cur=0;
} else { //遇到运算符就弹出两个操作数进行运算
int a = st.top();
st.pop();
int b = st.top();
st.pop();
int t=operate(b, a, s);
st.push(t);
}
}
return st.empty() ? 0 : st.top();//最后的结果为栈顶元素
}
int main() {
string str = "((1+8)*5+158)";
string tmp=prework(str);//添加‘#’号分离数字
tmp=exchange(tmp);//转后缀表达式
cout << calculate(tmp) << endl;//求值
return 0;
}