前缀表达式 (Prefix Notation) 是指将运算符写在前面操作数写在后面的不包含括号的表达式,而且为了纪念其发明者波兰数学家Jan Lukasiewicz所以前缀表达式也叫做“波兰表达式”。比如- 1 + 2 3
后缀表达式(Postfix Notation) 与之相反,是指运算符写在操作数后面的不含括号的算术表达式,也叫做逆波兰表达式。比如1 2 3 + -
后缀表达式(Postfix Notation) 与之相反,是指运算符写在操作数后面的不含括号的算术表达式,也叫做逆波兰表达式。比如1 2 3 + -
中缀表达式(Infix Notation) 就是常用的将操作符放在操作数中间的算术表达式。前缀表达式和后缀表达式相对于中缀表达式最大的不同就是去掉了表示运算优先级的括号,比如1-2+3
人工转换中缀到前缀和后缀的方法,给定一个中缀表达式a+b*c-(d+e)
1首先将这个中缀表达式的所有运算加括号((a+(b*c))-(d+e))
2然后将所有运算符放到括号后面,这样就变成了((a(bc)* )+ (de)+ )-
3把所有括号去掉abc*+de+-,最后得出的结果就是后缀表达式
相反都移到括号前面 就是前缀表达式。
计算机实现中缀到后缀的转化 以及后缀表达式算值是通过栈实现的。
具体的算法 参见 《数据结构教程 (2)》 李春葆 清华大学
代码如下 中缀转后缀
void tranfer2PosfixExpression(char * exp, char postexp[])
{
struct
{
char data[MAXSIZE];
int top;
}op;
int i = 0;
op.top = -1;
while( *exp != '\0')
{
switch(*exp)
{
case '(':
op.top++; op.data[op.top] = *exp;
exp++;
break;
case ')':
while(op.data[op.top] != '(')
{
postexp[i++] = op.data[op.top];
op.top --;
}
op.top--;
exp++;
break;
case '+':
case '-':
while(op.top != -1 && op.data[op.top] != '(')
{
postexp[i++] = op.data[op.top];
op.top --;
}
op.top ++;
op.data[op.top] = *exp;
exp++;
break;
case '*':
case '/':
while(op.top != -1 &&
(op.data[op.top] == '*' || op.data[op.top] == '/'))
{
postexp[i++] = op.data[op.top];
op.top --;
}
op.top ++; op.data[op.top] = *exp;
exp++;
break;
case ' ':
exp++;
break;
default:
while (*exp >= '0' && *exp <= '9')
{
postexp[i++] = *exp;
exp++;
}
postexp[i++] = '#';
} // switch
}// while
while(op.top >= 0)
{
postexp[i++] = op.data[op.top];
op.top --;
}
postexp[i++] = '\0';
}
后缀表达式计算
float computeValue(char *postExp)
{
struct{
float data[MAXSIZE];
int top;
}st;
float d, a, b, c;
st.top = -1;
while(*postExp != '\0')
{
switch(*postExp)
{
case '+':
a = st.data[st.top];
st.top --;
b = st.data[st.top];
st.top --;
c = a + b;
st.top ++;
st.data[st.top] = c;
break;
case '-':
a = st.data[st.top];
st.top --;
b = st.data[st.top];
st.top --;
c = b - a;
st.top ++;
st.data[st.top] = c;
break;
case '*':
a = st.data[st.top];
st.top --;
b = st.data[st.top];
st.top --;
c = a * b;
st.top ++;
st.data[st.top] = c;
break;
case '/':
a = st.data[st.top];
st.top --;
b = st.data[st.top];
st.top --;
if (a != 0)
{
c = b / a;
}else
{
printf(" diveded by zero!! \n");
}
st.top ++;
st.data[st.top] = c;
break;
default:
d = 0;
while(*postExp >= '0' && *postExp <= '9')
{
d = 10*d + (*postExp - '0');
postExp++;
}
st.top++;
st.data[st.top] = d;
break;
}// end of switch
postExp++;
}// end of while
return st.data[st.top];
}
后缀表达式的好处:
1. 去除了 “(” 和 “)”
2. 后缀表达式运算时间比较稳定,而中缀表达式由于运算顺序不同运行时间相差较大。可见在时间复杂度和效率方面后缀表示方法要明显优于中缀表示方法。 适合计算机求解