我们熟知的中缀表达式在电脑中计算时应转化为后缀表达式。
如果把表达式看作一棵二叉树,则中缀表达式就是二叉树的中序遍历,后缀表达式就是二叉树的后序遍历。
下面讲讲如何将中缀表达式转变为后缀表达式:
1.建立运算符栈用于运算符的储存,运算符栈中的元素应始终保持:越往栈顶元素(即运算符)优先级越高。
2.预处理中缀表达式:如果一个加号或减号出现在中缀表达式的最前方或者是左括号的后面,则该符号代表正号或负号,在该符号的前面加上0。
3.顺序扫描中缀表达式,如果当前字符为数字则直接输出数字;如果当前字符为括号或者运算符,则进行第4步操作。
4.若当前运算符为'(',直接进栈;
若当前运算符为')',顺序出栈并输出至第一个'(', '('也要出栈但不输出;
若当前运算符为'+'或'-',则全部出栈(如有左括号则停止出栈)并输出(括号不输出),然后'+'和'-'入栈。
总而言之:若栈顶优先级大于等于当前元素优先级,则顺序出栈至栈顶元素优先级小于当前元素优先级,最后当前元素入栈。
5.重复第3步,直到表达式扫描完毕,最后栈中元素全部出栈。
关于后缀表达式的计算:(很简单,放轻松)
1.建一个栈储存数字。
2.顺序遍历后缀表达式:
若当前字符为数字则进栈;
若当前字符为运算符,则位于栈顶的两个数字出栈进行运算,运算结果入栈。
3.遍历结束,输出栈顶元素即为结果。
我编写的程序输入为中缀表达式,输出为它对应的后缀表达式和后缀表达式的运算结果。
**注意:输入的中缀表达式若含有括号应为英文括号'(',不能是中文括号'(' ,两种括号不同!!!。
代码如下:
#include"stdio.h"
#include"stdlib.h"
#include"conio.h"
#define STACKSIZE 250
typedef struct{
char *base;
char *top;
char stacksize;
}SqStack;
void InitStack(SqStack &S) //创建一个空栈
{
S.base =(char *)malloc(STACKSIZE*sizeof(char));
if(!S.base) printf("储存分配失败!!\n");
else{
S.top=S.base ;
S.stacksize=STACKSIZE;
}
}
void Change()
{ int num=0,flag=1,a,b,pa=0;
char count;
char ch,e;
SqStack S1,S2;
InitStack(S1);
InitStack(S2);
printf("请输入中缀表达式:\n");
//ch=getchar();
ch=getchar();
while(ch!='\n')
{pa=1;
switch(ch)
{
case '+':
if((S1.top==S1.base&&flag==1)||(*(S1.top-1)=='('&&flag==1))
{
printf("%c",'0');*S2.top++='0';
}
else
while(S1.top!=S1.base&&num>0&&*(S1.top-1)!='(')
{
e=*--S1.top;
if(e=='*')
{
a=*--S2.top-48; //0的ASCll码为48
b=*--S2.top-48;
count=b*a+48;
*S2.top++=count;
}
if(e=='/')
{
a=*--S2.top-48;
b=*--S2.top-48;
count=b/a+48;
*S2.top++=count;
}
if(e=='+')
{
a=*--S2.top-48;
b=*--S2.top-48;
count=b+a+48;
*S2.top++=count;
}
if(e=='-')
{
a=*--S2.top-48;
b=*--S2.top-48;
count=b-a+48;
*S2.top++=count;
}
printf("%c",e);
num--;
}
*S1.top++=ch;
num++;
break;
case '-':
if((S1.top==S1.base&&flag==1)||(*(S1.top-1)=='('&&flag==1))
{
printf("%c",'0');*S2.top++='0';
}
else
while(S1.top!=S1.base&&num>0&&*(S1.top-1)!='(')
{
e=*--S1.top;
if(e=='*')
{
a=*--S2.top-48;
b=*--S2.top-48;
count=b*a+48;
*S2.top++=count;
}
if(e=='/')
{
a=*--S2.top-48;
b=*--S2.top-48;
count=b/a+48;
*S2.top++=count;
}
if(e=='+')
{
a=*--S2.top-48;
b=*--S2.top-48;
count=b+a+48;
*S2.top++=count;
}
if(e=='-')
{
a=*--S2.top-48;
b=*--S2.top-48;
count=b-a+48;
*S2.top++=count;
}
printf("%c",e);
num--;
}
*S1.top++=ch;
num++;
break;
case '*':
if(*(S1.top-1)=='*'||*(S1.top-1)=='/') {
e=*--S1.top;
if(e=='*')
{
a=*--S2.top-48;
b=*--S2.top-48;
count=b*a+48;
*S2.top++=count;
}
if(e=='/')
{
a=*--S2.top-48;
b=*--S2.top-48;
count=b/a+48;
*S2.top++=count;
}
printf("%c",e);
num--;
}
*S1.top++=ch;
num++;
break;
case '/':
if(*(S1.top-1)=='*'||*(S1.top-1)=='/')
{
e=*--S1.top;
if(e=='*')
{
a=*--S2.top-48;
b=*--S2.top-48;
count=b*a+48;
*S2.top++=count;
}
if(e=='/')
{
a=*--S2.top-48;
b=*--S2.top-48;
count=b/a+48;
*S2.top++=count;
}
printf("%c",e);
num--;
}
*S1.top++=ch;
num++;
break;
case '(':
*S1.top++=ch;
num++;
flag=1;
break;
case ')':
while(*(S1.top-1)!='('&&num>0&&S1.top!=S1.base){
e=*--S1.top;
if(e=='*')
{
a=*--S2.top-48;
b=*--S2.top-48;
count=b*a+48;
*S2.top++=count;
}
if(e=='/')
{
a=*--S2.top-48;
b=*--S2.top-48;
count=b/a+48;
*S2.top++=count;
}
if(e=='+')
{
a=*--S2.top-48;
b=*--S2.top-48;
count=b+a+48;
*S2.top++=count;
}
if(e=='-')
{
a=*--S2.top-48;
b=*--S2.top-48;
count=b-a+48;
*S2.top++=count;
}
printf("%c",e);
num--;
}
if(*(S1.top-1)=='(')
{
S1.top=S1.top-1;
num--;
}
break;
default:
if(flag==1) flag=0;
printf("%c",ch);
*S2.top++=ch;
break;
}
ch=getchar();
if(ch=='\n')
while(S1.top!=S1.base)
{ e=*--S1.top;
if(e=='*')
{
a=*--S2.top-48;
b=*--S2.top-48;
count=b*a+48;
*S2.top++=count;
}
if(e=='/')
{
a=*--S2.top-48;
b=*--S2.top-48;
count=b/a+48;
*S2.top++=count;
}
if(e=='+')
{
a=*--S2.top-48;
b=*--S2.top-48;
count=b+a+48;
*S2.top++=count;
}
if(e=='-')
{
a=*--S2.top-48;
b=*--S2.top-48;
count=b-a+48;
*S2.top++=count;
}
printf("%c",e);
}
}
if(pa==1)
printf("\n计算结果为:%d",count-48);
}
void MainMenu()
{
printf("******栈的线性储存之中缀后缀表达式转换(仅支持个位数的加减乘除括号)*******\n");
}
int main()
{
loop:
MainMenu();
Change();
printf("\n");
system("pause");
system("cls");
goto loop;
return 0;
}
运行结果如下:
、