中缀表达式即通用的算术或逻辑公式表示方法。如(1+2)*3-4。
后缀表达式即指的是不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则)。如中缀表达式(1+2)*3-4的后缀表达式为12+3*4-。
在将中序表达式转换为后序表达式过程中,使用到栈,运算符优先级高的先输出。下面算法中,将用icp来表示当前扫描到的运算符的优先级,该运算符进栈后的优先级为isp。优先级数如下表格:
中缀表达式转后缀表达式具体步骤为:
1、扫描到数字,直接输出;
2、扫描到运算符,若当前运算符icp大于栈顶运算符isp,进栈;
3、若icp小于isp,栈顶运算符出栈,并输出;
4、若icp==isp,栈顶运算符出栈,但不输出(两者相等情况为:“()”或”##”)。
代码如下:
//获取优先级函数
//flag==0: 获取isp;
//flag==1: 获取icp;
int getPriority(char opt,int flag)
{
int priority = -1;
if(flag==0){
switch(opt){
case '#':
priority = 0;
break;
case '(':
priority = 1;
break;
case '*':
priority = 5;
break;
case '/':
priority = 5;
break;
case '+':
priority = 3;
break;
case '-':
priority = 3;
break;
case ')':
priority = 6;
break;
default:
break;
}
}
else if(flag==1){
switch(opt){
case '#':
priority = 0;
break;
case '(':
priority = 6;
break;
case '*':
priority = 4;
break;
case '/':
priority = 4;
break;
case '+':
priority = 2;
break;
case '-':
priority = 2;
break;
case ')':
priority = 1;
break;
default:
break;
}
}
return priority;
}
//判断isp,icp优先级函数
//栈内运算符==栈外优先级 return 0 ;
//栈内运算符<栈外优先级 return 1;
//栈内运算符>栈外优先级 return 2;
int judgePriority(char isp,char icp)
{
int p1,p2;
p1 = getPriority(isp,0);
p2 = getPriority(icp,1);
if(p1==p2)
return 0;
else if(p1<p2)
return 1;
else
return 2;
}
//判断是否为数字
int judgeNumber(char ch)
{
if(ch>=48&&ch<=57)
return 1;
else
return 0;
}
//中序表达式以#结尾,如:a+b-a*((c+d)/e-f)+g#
//inexpress:中序表达式以
//postexpress用来存储后序表达式
void inToPostExpression(char *inexpress,char *postexpress)
{
char *isp;
int len,top=-1;
char ch1,ch2; //ch1位当前中序扫描到的字符,ch2表示已进栈的运算符
int i = 0;
int k = 0;
len = strlen(inexpress);
printf("expression: %s\n",inexpress);
//'#'符号入栈
isp = (char *)malloc(sizeof(char)*len);
isp[++top] = '#';
while(top>=0){
ch1 = inexpress[i++];
//判断ch1是否为数字?是,直接输出到后序表达式postexpress数组中
//否,判断优先级
if(judgeNumber(ch1)){
postexpress[k++] = ch1;
printf("%c",ch1);
continue;
}
//获取栈中运算符
ch2 = isp[top];
//若ch2<ch1,将ch1进栈
if(1==judgePriority(ch2,ch1)){
isp[++top] = ch1;
}
//若ch2>ch1,ch2出栈
else if(2==judgePriority(ch2,ch1)){
postexpress[k++] = ch2;
printf("%c",ch2);
top--;
i--; //i--,下次循环再判断ch1是否大于栈顶元素
}
else{
top--;
}
}
postexpress[k++]='\0';
printf("\n");
}