中缀表达式是我们人所常见的表达式,而后缀表达式是计算机使用的表达式。
例如有一个中缀表达式a*(b+c)/(d-e),我们手动转换为后缀表达式的过程为:按优先级把运算符放到操作数后。
在上面例子中,括号优先级最高,先计算括号里面的,a*(bc+)/(de-),其实可以去掉括号,在操作一步,abc+*de-/。
在计算机中把中缀表达式转换为后缀表达式常常用栈来实现。一个栈存放操作数,一个栈存放操作符。
1、遇到操作数,直接放到操作数栈。
2、如果不是操作数,分为以下几种情况
(1)如果操作符栈为空,则入栈
(2)如果栈非空,且栈顶操作符优先级大于当前操作符,则入栈;如果栈顶操作符优先级小于或等于栈顶操作符,则操作符栈出栈,直到栈顶操作符优先级小于当前操作符。
(3)如果是左括号'(',则入栈
(4)如果是右括号')',则操作符栈一直出栈,把出栈元素放到操作数栈,直到遇到左括号'('。
最后,如果操作符栈不为空,把操作符栈元素出栈,输入到操作数栈。
#include<iostream>
#include<stack>
#include<string>
/*
判断是否是操作符
@param c:字符
@return:ture or false
*/
inline bool isOperator(const char &c)
{
switch (c)
{
case '+':
case '-':
case '*':
case '/':
case '(':
case ')':
return true;
}
return false;
}
/*
判断操作符优先级
@param c:操作符
@return:+-优先级小于* /
*/
inline int priority(const char& c)
{
switch (c)
{
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
}
return 0;
}
/*
把中缀表达式转为后缀表达式
@param infix:中缀表达式
@return:后缀表达式
*/
std::string postfix(const std::string &infix)
{
std::stack<char> OperatorStack;
std::string post;
int len = infix.length();
for (int i = 0; i < len; ++i)
{
//如果是操作符
if (isOperator(infix[i]))
{
//如果是右括号,那么要找到左括号
if (infix[i] == ')')
{
char c;
while (true)
{
c = OperatorStack.top();
OperatorStack.pop();
if (c != '(')
post.push_back(c);
else
break;
}
}
//如果操作符栈为空或栈顶操作符优先级小于当前操作符,或者是左括号
else if (OperatorStack.empty() || (priority(infix[i])>priority(OperatorStack.top()))||infix[i]=='(')
OperatorStack.push(infix[i]);
//当前操作符优先级不低于栈顶操作符优先级
else if (priority(infix[i]) >= priority(OperatorStack.top()))
{
char c;
while (!OperatorStack.empty())
{
c = OperatorStack.top();
if (priority(c) >= priority(infix[i]))
{
OperatorStack.pop();
post.push_back(c);
}
else
break;
}
OperatorStack.push(infix[i]);
}
}
//否则就是操作数
else
post.push_back(infix[i]);
}
while (!OperatorStack.empty())
{
post.push_back(OperatorStack.top());
OperatorStack.pop();
}
return post;
}
int main()
{
std::string str = "a*(b+c)/(d-e)";
std::cout << postfix(str) << std::endl;
return 0;
}