中缀表达式=》后缀(逆波兰)表达式
例如:1+2=>1 2 +
分析原理:利用栈的记忆,符号推入栈,数字直接输出,当然有些时候在推入符号前,要先将栈内的元素Pop出来计算,再压入
具体分析1+(2-3)*4+10/5=》1 2 3 - 4 × + 10 5 / +
1.首先遇到第一个输入是数字1,数字在后缀表达式中都是直接输出,接着是符号”+“,入栈;
2.第三个字符是”(“,依然是符号,入栈,接着是数字2,输出,然后是符号”-“,入栈;
3.接下来是数字3,输出,紧跟着是”)“,此时,我们需要去匹配栈里的”(“,然后匹配前将栈顶数据依次出栈(这就好比括号里优先执行的道理)(遇”(“停止出栈);
4.紧接着是符号”ד,直接入栈;
5.遇到数字4,输出,之后是符号”+“,此时栈顶元素是”ד,按照先乘除后加减原理,此时栈顶的乘号优先级比即将入栈的加号大,所以出栈;栈中第二个元素是加号,按理应平起平坐,但也要透透气,同理如果栈中还有其他操作符都要出栈;最后再”+“入栈;
6.紧接着数字10,输出,最后是符号”/”,进栈;
7.最后一个数是5,输出,所有输入处理完毕,但栈中仍然有数据,所以将栈中的符号依次出栈
中缀表达式转化为后缀表达式
/*************************************************************************
> File Name: 中缀转后缀.c
> Author: geeker
> Mail: 932834897@qq.com
> Created Time: 2017年02月04日 星期六 20时16分15秒
************************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<ctype.h>
#define stacksize 20
#define maxbuffer 10//最大缓冲区
typedef char ElemType;
typedef struct
{
ElemType *base;
ElemType *top;
int maxsize;
}sqStack;
void InitStack(sqStack *s)//初始化
{
s->base=(ElemType *)malloc(stacksize * sizeof(ElemType));
if(!s->base)
exit(0);
s->top=s->base;
s->maxsize=stacksize;
}
void Push(sqStack *s,ElemType e)//压栈
{
if(s->top-s->base>=s->maxsize)
return;
*(s->top)=e;
s->top++;
}
void Pop(sqStack *s,ElemType *e)//出栈
{
if(s->top==s->base)
return;
*e=*--(s->top);
}
int StackLen(sqStack s)//(看清s不是指针),计算当前容量
{
return(s.top-s.base);//点是结构不是指针
}
int main()
{
sqStack s;
char c,e;
InitStack(&s);
printf("请输入中缀表达式,以#作为结束标志\n");
scanf("%c",&c);
while(c!='#'){ //scanf一共接受了两次,所以怕第一次接受会将#过滤掉直接打印了,所以还要再弄一次判断#
while(c>='0'&&c<='9')//这里用while而不用if的原因是如果输入连续的数值比如10,但输出的RPN不知道是10 还是1和0
{
printf("%c",c);
scanf("%c",&c);
if(c<'0'||c>'9')
{
printf(" ");
}
}
if(')'==c)//这个书写方式很重要。如果相等,则将栈的数据出栈,直到(,匹配过程结束
{
Pop(&s,&e);
while('('!=e)
{
printf("%c ",e);
Pop(&s,&e);//再弹栈
}
}
else if('+'==c||'-'==c)//根据先乘除后加减,如果栈顶是乘除,若准备将加减或右括号压栈,那就得先将栈顶元素一次输出来,形成空栈,再压栈。
{
if(!StackLen(s))//如果栈本来就是空的,那就直接压入
{
Push(&s,c);
}
else
{
do
{
Pop(&s,&e);
if('('==e)
{
Push(&s,e);
}
else
{
printf("%c",e);
}
}while(StackLen(s)&&'('!=e);
Push(&s,c);//最后放进去
}
}
else if('*'==c||'/'==c||'('==c)
{
Push(&s,c);
}
else if('#'==c)
{
break;
}
else
{
printf("\n出错,输入程序错误\n");
return -1;
}
scanf("%c",&c);
}
while(StackLen(s)!=0)//最后如果栈内还有元素,都拿出来
{
Pop(&s,&e);
printf("%c ",e);
}
return 0;
}
本文介绍了一种将中缀表达式转换为后缀(逆波兰)表达式的算法,并通过实例详细解析了转换过程。同时提供了一个简单的C语言实现示例。
1028

被折叠的 条评论
为什么被折叠?



