中缀表达式转后缀表达式
依旧利用栈这种数据结构,本文只是以+、-、*、/、()几个运算符为例,有兴趣的小伙伴可以自己拓展。
如何将a + b * c + ( d * e + f ) * g形式的中缀表达式转换成后缀表达式呢?
先上正确答案,abc*+de*f+g*+。
步骤如下:
· 建立一个空栈;
· 遍历字符串。当读到操作数时,直接输出;
· 当读到运算符时:
a 若为 ‘(‘,入栈;
b 若为 ‘)’,则依次把栈中的的运算符加入后缀表达式中,直到出现’(‘,从栈中删除’(’ ;
c 若为除括号外的其他运算符, 当其优先级高于除’(‘以外的栈顶运算符时,直接入栈。
d 否则,依次弹出比当前处理的运算符优先级高和优先级相等的运算符,直到一个比它优先级低的或者遇到了一个左括号为止。
e 遍历结束时,栈中的所有运算符出栈;
那废话不多说,直接上代码。第一个函数int sortOperator(char c)主要是给运算符规定优先顺序,方便后续判断,可以看出如果想添加运算符种类的话,在这个函数扩展也很方便;第二个函数void infixToPostfix(string expression)就是实现转换的函数了。
#include <iostream>
#include <stack>
#include <string>
using namespace std;
int sortOperator(char c) {
switch (c)
{
case ')':
return 0;
case '*':
return 1;
case '/':
return 1;
case '+':
return 2;
case '-':
return 2;
case '(':
return 3;
default:
return -1;
}
}
void infixToPostfix(string expression){
stack<char> s;
for (int i = 0; i < expression.length();i++) {
//字母代表操作数,直接输出
if (expression.at(i) >= 'a' && expression.at(i) <= 'z') {
cout << expression.at(i) << "";
}
//去除空格
else if (expression.at(i) == ' ') {}
else
switch (expression.at(i)){
//左括号直接入栈
case '(':
s.push(expression.at(i));
break;
//同级运算符写一种就可以,因为sortOperator返回值相同,这里未做省略
//这里还要注意sortOperator的返回值和实际运算优先级相反,
//也可调整为和实际运算优先级相同,方便理解。
case'*':
//栈非空,且栈顶运算符优先级高于或等于当前运算符,出栈并输出,直到栈顶运算符
//优先级低于当前运算符,该运算符入栈
while (!s.empty() &&
sortOperator(s.top()) <= sortOperator('*')) {
cout << s.top();
s.pop();
}
s.push(expression.at(i));
break;
case '/':
while (!s.empty() &&
sortOperator(s.top()) <= sortOperator('/')) {
cout << s.top();
s.pop();
}
s.push(expression.at(i));
break;
case '+':
while (!s.empty() &&
sortOperator(s.top()) <= sortOperator('+')) {
cout << s.top();
s.pop();
}
s.push(expression.at(i));
break;
case '-':
while (!s.empty() &&
sortOperator(s.top()) <= sortOperator('-')) {
cout << s.top();
s.pop();
}
s.push(expression.at(i));
break;
case ')':
//遇到右括号,一直进行出栈操作并输出,直到遇到左括号结束循环,再将左括号
//出栈,且不输出
while (!s.empty() && s.top() != '(')
{
cout << s.top() << "";
s.pop();
}
s.pop();
break;
default:
break;
}
}
//遍历表达式后,栈内所有操作符依次出栈并输出。
while (!s.empty())
{
cout << s.top() << "";
s.pop();
}
cout << endl;
}
测试代码如下,
int main(int argc, char* argv[])
{
cout << "input expression" << endl;
string line;
getline(cin, line);
infixToPostfix(line);
system("pause");
return 0;
}
有兴趣的小伙伴,可以尝试多添加几种运算符,^, ! 等等。