数据结构实验之栈与队列二:一般算术表达式转换成后缀式

Problem Description
对于一个基于二元运算符的算术表达式,转换为对应的后缀式,并输出之。

Input
输入一个算术表达式,以‘#’字符作为结束标志。

Output
输出该表达式转换所得到的后缀式。

Sample Input
ab+(c-d/e)f#
Sample Output
ab
cde/-f
+
题解:
根据一般算术表达式转换成后缀式的规则,在用代码实现时,需要将原表达式遍历一遍,可以具体分为以下几种情况:
当碰到字母时,直接输出,作为后缀式的一部分。
当碰到运算符+ -*/的时候就要分情况讨论,若此时栈为空,运算符直接入栈。若此时栈不空,这个运算符就要和栈顶的运算符进行级别高低的比较,若这个运算符级别高于栈顶运算符,则入栈,否则栈顶运算符出栈,这个运算符再入栈。(这样操作是为了做到遵循运算法则先乘除后加减,先运算级别高的运算符所在的式子,并且先左后右计算)。
当碰到括号时,若为左括号,直接入栈,若为右括号,则把栈内直到左括号的元素依次输出。
当碰到‘#’时说明原表达式遍历完了,此时若栈内还有元素,则栈内的元素依次出栈。

#include <stdio.h>
#include <stdlib.h>
#define stackinitsize 100
#define stackcreat 10
#define ok 1
#define overflow -1
#define error -1
typedef int elemtype;
typedef struct
{
    elemtype *base;
    elemtype *top;
    int stacksize;

} sqstack;
int initstack(sqstack *s)
{
    s->base=(elemtype*)malloc(stackinitsize*sizeof(elemtype));
    if(!s->base)exit(overflow);
    s->top=s->base;
    s->stacksize=stackinitsize;
    return ok;

}
int push(sqstack *s,elemtype e)
{
    if(s->top-s->base>=s->stacksize)
    {
        s->top=(elemtype*)realloc(s->base,(s->stacksize+stackcreat)*sizeof(elemtype));
        if(!s->base)exit(overflow);
        s->top=s->base+s->stacksize;
    }
    *s->top++=e;
    return ok;

}
int pop(sqstack *s)
{
    if(s->top==s->base)return error;
    s->top--;
    return ok;

}
int stackempty(sqstack *s)
{
    if(s->top==s->base)return 1;
    else return 0;

}
char gettop(sqstack *s)
{
    char e;
    if(s->top==s->base)return error;
    e=*(s->top-1);
    return e;
}
int bijiao(char a,char b)//用于比较运算符优先级高低的函数
{
    if(((a=='*'||a=='/')&&(b=='+'||b=='-'))||((a=='+'||a=='-')&&(b=='+'||b=='-'))||((a=='*'||a=='/')&&(b=='*'&&b=='/')))
        return 1;
    else return 0;

}
int main()
{
    char c,e;
    sqstack s;
    initstack(&s);
    while(scanf("%c",&c)!=EOF)
    {
        if(c!='#')
        {
            if(c>='a'&&c<='z')printf("%c",c);//如果是字符直接输出
            else if(c=='+'||c=='-'||c=='*'||c=='/')//如果是运算符要分情况
            {
                if(stackempty(&s))push(&s,c);//如果栈为空,直接入栈
                else
                {
                    e=gettop(&s);
                    if(bijiao(e,c)==1)//输入的运算符不比栈顶运算符级别高
                    {
                        printf("%c",e);//输出栈顶运算符
                        pop(&s);//栈顶运算符出栈
                        push(&s,c);//输入的运算符入栈

                    }
                    else push(&s,c);//直接入栈

                }


            }
            else if(c=='('||c==')')//为括号的情况
            {
                if(c=='(')push(&s,c);
                if(c==')')
                {
                    e=gettop(&s);
                    while(e!='(')
                    {
                        printf("%c",e);
                        pop(&s);
                        e=gettop(&s);

                    }
                    if(e=='(')pop(&s);

                }

            }

        }
        if(c=='#')//最后把剩余的元素输出
        {
            while(!stackempty(&s))
            {
                e=gettop(&s);
                printf("%c",e);
                pop(&s);

            }
            printf("\n");
            break;
        }


    }

    return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值