栈与队列(三)中缀表达式转后缀表达式

本文介绍了一种将中缀表达式转换为后缀(逆波兰)表达式的算法,并通过实例详细解析了转换过程。同时提供了一个简单的C语言实现示例。

中缀表达式=》后缀(逆波兰)表达式

例如: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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值