转来的,仅仅作为以后复习用途。http://blog.csdn.net/zsuguangh/article/details/6280863
例如:中序表达式(23+34*45/(5+6+7))转换成后序表达式23 34 45 * 5 6 + 7 + / +
后序表达式用处:
当转换成后序表达式后更方便计算表达式的值,如将后序表达式的元素依次进栈直到遇到运算符,这时候从栈中弹出两个元素,再结合运算符计算出这两个数运算的结果(如34*45=1530),将其结果压栈(此时栈元素为23 1530),然后继续将后序非符号元素压栈,直到遇到运算符。重复之前的操作。。。
InfixExp(中序表达式)转换PostfixExp(后序表达式)算法:
1)当输入的是操作数时候,直接输出到后序表达式PostfixExp序列中
2)当输入开括号时候,把它压栈
3)当输入的是闭括号时候,先判断栈是否为空,若为空,则发生错误并进行相关处理。若非空,把栈中元素依次弹出并输出到Postfix中,知道遇到第一个开括号,若没有遇到开括号,也发生错误,进行相关处理
4)当输入是运算符op(+、- 、×、/)时候
a)循环,当(栈非空and栈顶不是开括号and栈顶运算符的优先级不低于输入的运算符的优先级)时,反复操作:将栈顶元素弹出并添加到Postfix中
b)把输入的运算符op压栈
5)当中序表达式InfixExp的符号序列全部读入后,若栈内扔有元素,把他们依次弹出并放到后序表达式PostfixExp序列尾部。若弹出的元素遇到空括号,则说明不匹配,发生错误,并进行相关处理
参考文献许卓群版《数据结构与算法》
贴上网上找到的代码:
/****************************/
/* www.afdream.com */
/* Author:Fdream */
/* 引用此算法请保留此信息 */
/****************************/
#include<iostream.h>
const int MAX=40;
void main(void){
char infix[MAX]={'#'};
char oprator[MAX]={'@','#'};
int opr=1;
char postfix[12]={'#'};
int post=0;
int i,j,cnt=0,cntl;
char c;
//输入表达式,以等号结束
cin.get(c);
while(c!='='){
infix[cnt]=c;
cnt++;
cin.get(c);
}
cntl=cnt;
for(i=0;i<cnt;i++){
switch(infix[i]){
//左括号就直接入栈
case '(':
cntl=cntl-2;
oprator[opr]=infix[i];
opr++;
break;
//右括号则先退栈,直到遇见第一个左括号
case ')':
for(j=opr-1;j>0;j--){
if(oprator[j]!='('){
postfix[post]=oprator[j];
oprator[j]='#';
post++;
}
else{
oprator[j] = '#';
break;
}
}
opr=j;
break;
case '*':
case '/':
//如果前一个运算符为*或/,则先退栈,再入栈,否则直接入栈
if (oprator[opr] == '*' || oprator[opr] == '/') {
postfix[post] = oprator[opr];
oprator[opr]='#';
post++;
}
oprator[opr] = infix[i];
opr++;
break;
case '+' :
case '-' :
//如果上一个运算符不是左括号也不是栈顶,则先退栈再入栈
if (oprator[opr-1] != '(' && oprator[opr-1] != '@') {
postfix[post] = oprator[opr];
oprator[opr]='#';
}
oprator[opr] = infix[i];
opr++;
break;
default :
//如果是数字则直接进入后缀表达式数组
postfix[post] = infix[i];
post++;
break;
}
}
//如果扫描完成,则退栈
for(j=opr-1;j>0;j--){
if(oprator[j]!='@'){
postfix[post]=oprator[j];
oprator[j]='#';
}
else
break;
}
//输出结果
for(i=0;i<cntl;i++)
cout << postfix[i];
cout << endl;
}