简单的中缀表达式转后缀表达式
这里的简单指的是表达式简单,所有数字都是个位数,不是代码简单
中缀表达式就是我们平时最经常使用的,例:(1+2)*3-4
后缀表达式就是把运算符放到运算数后面
【后缀表达式传送门】
转换思路
- 假设输入的中缀表达式的字符串为 str
- 需要一个栈 s 来作为临时的先进后出的存储结构
- 需要一个字符串 result 来保存最终的结果
- 从左到右遍历中缀表达式,按照一定的规则将不同的运算符或数字加入到 s 或者 result中
具体规则为:
规定当前读取的 str[i] 的某一个字符为 c
- 如果c是数字,直接加入结果串 result 中
- 如果c是左括号(,直接加入栈 s 中
- 如果c是右括号),逐步倒出栈中的符号,并将他们加入结果串 result 中,直到栈顶出现左括号(,然后倒出这个左括号
- 如果c是运算符,比较c与栈顶元素的优先关系,如果优先,则直接进栈,否则逐步倒出栈中元素并加入结果串 result ,直到遇到栈顶元素优先级低于c,将c进栈
代码
#include <iostream>
#include <string>
#include <stack>
#include <map>
using namespace std;
#define char2int(x) ((int)(x - '0'))
#define int2char(x) ((char)(x + '0'))
// 使用map结构存储运算符的优先级别
typedef pair<char, int> p;
map<char, int> m;
void minit()
{
// #号防止空栈,故优先为最低
m.insert(p('#', -1));
m.insert(p('+', 1));
m.insert(p('-', 1));
m.insert(p('*', 2));
m.insert(p('/', 2));
}
int main()
{
string str;
cin>>str;
// 栈中加入一个'#'防止空栈
stack<char> s;
s.push('#');
// 结果串,map初始化
string result = "";
minit();
// 从左到右遍历中缀表达式串
for(int i=0; i<str.length(); i++)
{
char c = str[i];
if('0'<=c && c<='9')
{
result += c;
}
else if(c == '(')
{
s.push(c);
}
else if(c == ')')
{
while(s.top() != '(')
{
result += s.top();
s.pop();
}
s.pop();
}
else
{
while(1)
{
if(s.top()=='(' || m[s.top()]<m[c])
{
break;
}
result += s.top();
s.pop();
}
s.push(c);
}
}
while(s.top() != '#')
{
result += s.top();
s.pop();
}
cout<<result<<endl;
return 0;
}
表达式树
- 运算数字放在叶子节点,符号放在根节点
- 一个根节点代表一个运算的结果
- 一个根节点的运算结果可以递归地表示为:
左子树的运算结果 运算 右子树的运算结果
- 后序遍历表达式树,得到后缀表达式