输入中缀表达式样例:
2+48+(88+1)/3
输出后缀表达式样例:
248*+88*1+3/+
对于中缀表达式转换为后缀表达式,我们需要用以下步骤来解决这个问题:
//首先定义优先级
#include
#include
#include
using namespace std;
int priority(const char ch)
{
// */优先级相同最大
int priority = 0;
if (ch == '*' || ch == '/')
priority = 2;
else if (ch == '+' || ch == '-')
priority = 1;
else if (ch == '(')
priority = 0;
else
//其他字符优先级错误
priority = -1;
return priority;
}
string turnPostfix(string &str)
{
stack<char> st;
string ret; //保存中缀转后缀的结果
for (int i = 0; i < str.size(); i++)
{
// cout << str[i] << endl;
//如果这个字符没有优先级,说明这个字符不是操作符
if (priority(str[i]) == -1 && str[i] != ')')
{
//字符直接输出
ret.push_back(str[i]);
}
else
{
if (st.empty())
{
st.push(str[i]);
}
else
{
//如果str[i]==)将栈输出,直到(
if (str[i] == ')')
{
while (st.top() != '(')
{
ret.push_back(st.top());
st.pop();
}
//将(弹出栈
st.pop();
}
else
{
//如果是(直接入栈
if (str[i] == '(')
{
st.push(str[i]);
}
else
{
//将优先级大于这个操作符的字符出栈输出
//cout << "INFO:" << st.top() << endl;
while (!st.empty() && priority(st.top()) >= priority(str[i]))
{
ret.push_back(st.top());
st.pop();
}
//将这个操作符号入栈
st.push(str[i]);
}
}
}
}
}
//将栈剩下的元素全部出栈
while (!st.empty())
{
ret.push_back(st.top());
st.pop();
}
return ret;//调用string的拷贝构造函数返回
}
int main()
{
//string input = "2+4*8+(8*8+1)/3";
string input = "a*(b+c)-d";
cout << turnPostfix(input) << endl;
return 0;
}
整体思路正好于后缀相反
输入中缀表达式:(a+b) * (c+d)
输出前缀表达式为: * ,+,a,b,+,c,d。
初始化一个运算符栈st
从右至左扫描中缀表达式,从右边第一个字符开始判断。
//首先定义优先级
#include
#include
#include
#include
using namespace std;
int priority(const char ch)
{
// */优先级相同最大
int priority = 0;
if (ch == '*' || ch == '/')
priority = 2;
else if (ch == '+' || ch == '-')
priority = 1;
else if (ch == ')')
priority = 0;
else
//其他字符优先级错误
priority = -1;
return priority;
}
string turnPrefix(const string &str)
{
string ret;
stack<char> st;
for (int i = str.length() - 1; i >= 0; i--)
{
// cout << str[i] << " " << endl;
if (priority(str[i]) == -1 && str[i] != '(')
{
//数字,直接输出到ret上即可
ret.push_back(str[i]);
}
else
{
if (str[i] == '(')
{
//弹出栈,直到遇到)
while (st.top() != ')')
{
ret.push_back(st.top());
st.pop();
}
//将')'弹出栈
st.pop();
}
else
{
if (st.empty())
{
st.push(str[i]);
}
else
{
if (str[i] == ')')
{
//右括号直接入栈
st.push(str[i]);
}
else
{
//栈优先级大的出栈
while (!st.empty() && priority(st.top()) > priority(str[i]))
{
ret.push_back(st.top());
st.pop();
}
//将这个操作符入栈
st.push(str[i]);
}
}
}
}
}
while (!st.empty())
{
ret.push_back(st.top());
st.pop();
}
std::reverse(ret.begin(), ret.end());
return ret;
}
int main()
{
string input = "1+((2+3)*4)-5";
cout << turnPrefix(input) << endl;
return 0;
}
#include
#include
#include
#include
#include
using namespace std;
//传入后缀表达式
int PostfixToNumber(const string &str)
{
std::map<char, std::function<int(int, int)>> opMap ={
{'+', [](int x, int y){ return x + y; }},
{'-', [](int x, int y){ return x - y; }},
{'*', [](int x, int y){ return x * y; }},
{'/', [](int x, int y){ return x / y; }},
};
stack<int> st;
for (int i = 0; i < str.length(); i++)
{
if (str[i] >= '0' && str[i] <= '9')
{
st.push(str[i] - '0');
}
else
{
int right = st.top();
st.pop();
int left = st.top();
st.pop();
//实际上就是switch case 不同的运算符执行不同的运算,我这里使用C++11包装器
st.push(opMap[str[i]](left,right));
}
}
return st.top();
}
int main()
{
//"2+4*8+(8*8+1)/3"
cout<<PostfixToNumber("248*+88*1+3/+")<<endl;
}
创建一个数字栈
从右至左扫描表达式,从右边第一个字符开始判断如果当前字符(或字符串)为数字或变量,则直接压入数字栈内;如果是运算符,则弹出两个数字运算;如此反复,直到读完整个表达式;
需要注意:
后缀表达式右值为第一个栈顶元素,左值为第二个栈顶元素
前缀左值为第一个栈顶元素,右值为第二个栈顶元素
#include
#include
#include
#include
#include
using namespace std;
//传入前缀表达式
int PrefixToNumber(const string &str)
{
std::map<char, std::function<int(int, int)>> opMap ={
{'+', [](int x, int y){ return x + y; }},
{'-', [](int x, int y){ return x - y; }},
{'*', [](int x, int y){ return x * y; }},
{'/', [](int x, int y){ return x / y; }},
};
stack<int> st;
for (int i = str.length() - 1; i >= 0; i--)
{
if (str[i] >= '0' && str[i] <= '9')
{
st.push(str[i] - '0');
}
else
{
int left = st.top();
st.pop();
int right = st.top();
st.pop();
st.push(opMap[str[i]](left,right));
}
}
return st.top();
}
int main()
{
//1+((2+3)*4)-5
cout<<PrefixToNumber("-+1*+2345")<<endl;
return 0;
}
参考博客: