总体上来说中缀转后缀还算比较难,因为我们习惯了中缀表达式的运算和写法,所以初次编写很难理解,不过只要理解了算法的核心,编程也简单多了,这个代码是基于数据结构书上的代码改编而来,并没有使用优先级表格(这里需要说明:不使用表格的唯一坏处就是当运算符栈顶元素不为空时,左右括号的优先级很难确定比较,容易导致出错,我是用的方法是将左括号的优先级设为最高级,使他优先进栈这样既不影响优先级比较又能实现左右括号的优先级确定),但是优先级的思想是必不可少的。
当然这个算法并不是最优的,我还看到有可以使用括号来进行表达式转换的算法,具体是:
*先将所有的计算式按优先级加括号如:4+8/(5+4) 加括号后转化为
(4+(8/(5+4)))
然后将运算符移至括号后变成
(4(8(54)+)/))+
最后去掉括号
4854+/+
也可用此法转换前缀表达式*
我这里只是提供这种思想具体还请自行编写。
#include<iostream>
#include<stdlib.h>
using namespace std;
struct oprate
{
char data[100];
int top;
}op;
int OperateJudge(char e)
{
if (e == '(')
return 0;
else if (e == '+' || e == '-')
return 1;
else if (e == '*' || e == '/')
return 2;
else if (e == ')')
return 0;
else if (e == '=')
return -2;
else
return -1;
}
int Precede(char op1, char op2)
{
int a, b;
a = OperateJudge(op1);
b = OperateJudge(op2);
if (a == b)
return 0;
else if (a > b)
return -1;
else if (a < b)
return 1;
}
void Trans(char *exp, char postexp[])
{
int i = 0;
op.top = -1;
op.top++;
op.data[op.top] = '=';
while (*exp != '\0')
{
if (OperateJudge(*exp) == -1)
{
postexp[i++] = *exp;
exp++;
postexp[i++] = '#';
}
else
{
if (*exp == '(')
{
op.data[++op.top] = *exp;
exp++;
continue;
}
switch(Precede(op.data[op.top], * exp))
{
case 1:
op.data[++op.top] = *exp;
exp++;
break;
case 0:
op.top--;
exp++;
break;
case -1:
postexp[i++] = op.data[op.top--];
break;
}
}
}
while (op.data[op.top] != '=')
postexp[i++] = op.data[op.top--];
postexp[i] = '\0';
}
void Dispexp(char postexp[])
{
int i = 0;
for (i = 0;postexp[i] != '\0';i++)
{
if (postexp[i] != '#')
cout << postexp[i];
}
}
int main()
{
char exp[100], postexp[100];
cin >> exp;
Trans(exp, postexp);
Dispexp(postexp);
return 0;
}