计算后缀表达式只用到一个栈,因此很多情况下需要将中缀表达式转换成后缀表达式,以方便进行计算。
使用条件:只能出现二元操作符加减乘除,不能出现负号等一元操作符
1. 如果中缀表达式以全括号形式表示,则可以使用以下代码实现转换:
#include <iostream>
#include <string>
#include <cctype>
#include <cassert>
#include <stack>
using namespace std;
bool is_operation(const char& ch) {
if(ch == '+' || ch == '-' || ch == '*' || ch== '/')
return true;
return false;
}
//将全括号形式的中缀表达式转化成后缀表达式
void infix_to_postfix(istream &ins) {
char ch;
double num;
stack<char> chstack;
while(ins && ins.peek() != '\n') {
if(ins.peek() == '(') {
ins >> ch;
chstack.push(ch);
}
else if(isdigit(ins.peek()) || ins.peek() == '.') {
ins >> num;
cout << num << " ";
}
else if(is_operation(ins.peek())) {
ins >> ch;
chstack.push(ch);
}
else if(ins.peek() == ')') {
ins.ignore();
assert(!chstack.empty()); //表达式右边有多余')',此时栈已为空
assert(is_operation(chstack.top())); //缺少操作符
cout << chstack.top() << " ";
chstack.pop();
assert(chstack.top() == '('); // 括号不匹配
chstack.pop();
}
else ins.ignore();
}
assert(chstack.empty()); // 表达式左边有多余'('
}
int main() {
infix_to_postfix(cin);
cout << endl;
return 0;
}
2. 一般情况下,表达式多数不表示成全括号形式,此时需要使用计算优先级规则进行设计
代码实现如下:
#include <iostream>
#include <string>
#include <cctype>
#include <cassert>
#include <stack>
using namespace std;
bool is_operation(const char& ch) {
if(ch == '+' || ch == '-' || ch == '*' || ch== '/')
return true;
return false;
}
//比较操作符的优先级
bool precede(const char &ch1, const char& ch2) {
if(ch2 =='+' || ch2 == '-')
return true;
else if(ch1 == '*' || ch1 == '/')
return true;
return false;
}
//将中缀表达式转换成后缀表达式
void infix_to_postfix(istream &ins) {
char ch;
double num;
stack<char> chstack;
while(ins && ins.peek() != '\n') {
if(ins.peek() == '(') {
ins >> ch;
chstack.push(ch);
}
else if(isdigit(ins.peek()) || ins.peek() == '.') {
ins >> num;
cout << num << " ";
}
//遇到操作符时,循环输出栈顶元素并出栈,直到(1)栈为空(2)遇到'(' (3) 栈中的操作符优先级小于输入的操作符
else if(is_operation(ins.peek())) {
while( !chstack.empty() && chstack.top() !='(' && precede(chstack.top(), ins.peek()) ) {
cout << chstack.top() << " ";
chstack.pop();
}
ins >> ch;
chstack.push(ch);
}
//遇到')'时,循环输出栈中元素直到遇到'('
else if(ins.peek() == ')') {
ins.ignore();
assert(!chstack.empty()); //表达式右边有多余')',此时栈已为空
while(chstack.top()!= '(' && !chstack.empty()) {
cout << chstack.top() << " ";
chstack.pop();
}
assert(chstack.top() == '('); // 括号不匹配
chstack.pop();
}
else ins.ignore();
}
while(!chstack.empty()) {
assert(chstack.top()!= '('); // 表达式左边有多余'('
cout << chstack.top() << " ";
chstack.pop();
}
}
int main() {
infix_to_postfix(cin);
cout << endl;
return 0;
}