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

Problem Description

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

Input

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

Output

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

Example Input

a*b+(c-d/e)*f#

Example Output

ab*cde/-f*+

Think: 一道栈的题。根据题意就知道要想实现将原式改成后缀式(满足原式的计算顺序),建立一个栈显然不够,于是就一个栈来存运算数,如abc,另一个来存运算符,如+-*/(),而这个栈要在适合的时机还要进入一开始存运算数的栈(最后的归宿)。而这个入栈、出栈的时机是什么呢?小伙伴先思考思考,可以举题目里的栗子,模拟出先后顺序。。。↖(^ω^)↗

无添加的纯C代码如下,咕咚咕咚,隔~~~好喝^_^

#include<stdio.h>
#include<string.h>
#include<malloc.h>
#define MAX 1001  //栈的大小,可以多加几个0
typedef char Elem;
typedef struct
{
    int base;
    int top;
    Elem *data;
    int size;
}stack;  //栈
void Init(stack *s);  //初始化栈
void Push(stack *s, int k);  //压栈(入栈)
void Pop(stack *s);  //出栈
int Empty(stack *s);  //判断栈是否为空
int f(char a);  //为了便于知道运算符的优先级,返回一个值来便于后续操作
char Gettop(stack *s);  //返回栈顶元素
void Show(stack *s);  //输出栈
int main()
{
    char c, cc;
    stack s, t;
    Init(&s); //存运算数、符的栈初始化
    Init(&t); //临时存运算符的栈初始化
    while(scanf("%c", &c)&&c != '#'){
        if(c != '+'&&c != '-'&&c != '*'&&c != '/'&&c != '('&&c != ')'){
            Push(&s, c);  //如果为运算数直接进入栈s
        }
        else{  //否则为运算符
            if(Empty(&t)||c == '(')  //如果为左括号或者临时存运算符的栈为空,直接进栈t
                Push(&t, c);
            else if(c == ')'){
                while(!Empty(&t)){  //如果栈t,不为空,把栈t里在左括号后入栈的元素,从栈顶依次入栈s
                    cc = Gettop(&t);
                    if(cc != '('){
                        Push(&s, cc);
                        Pop(&t);
                    }
                    else{  //如果右括号遇到左括号,那么,它俩就牵着小手离开了集体。。。
                        Pop(&t);
                        break;
                    }
                }
            }
            else{  //如果c是运算符*/+-,当然我们学过数学都知道*/的运算优先于+-
                int b = f(c);
                while(!Empty(&t)){
                    cc = Gettop(&t);
                    int k = f(cc);
                    if(b <= k&&k != 4){  //左括号等待的“人”只有右括号
                        Push(&s, cc);    //如果当前运算符的优先级不大于栈t的栈顶,就要改入栈s, and从栈t出栈
                        Pop(&t);
                    }
                    else break;
                }
                Push(&t, c);  //等待入栈的元素c不能忘!!!
            }
        }
    }
    while(!Empty(&t)){ //如果临时栈t,不空,就要按从栈顶到栈低的顺序依次入栈s
        cc = Gettop(&t);
        Push(&s, cc);
        Pop(&t);
    }
    Show(&s);  //输出栈s
    return 0;  //结束了,上面的代码是根据规律来的,一定要举个栗子,动手模拟一下这波神奇的操作,便于理解
}
void Init(stack *s)
{
    s->data = (Elem *)malloc(MAX * sizeof(Elem));
    if(!s->data) exit(0);
    s->top = s->base = 1;
    s->size = MAX;
}
void Push(stack *s, int k)
{
    s->data[s->top++] = k;
}
void Pop(stack *s)
{
    s->top--;
}
int f(char a)
{
    if(a == '(')
        return 4;
    else if(a == '*'||a == '/')
        return 2;
    else if(a == '-'||a == '+')
        return 1;
    return 0;
}
char Gettop(stack *s)
{
    return s->data[s->top - 1];
}
int Empty(stack *s)
{
    if(s->top == s->base)
        return 1;
    return 0;
}
void Show(stack *s)
{
    while(s->base < s->top){
        printf("%c", s->data[s->base++]);
    }
    printf("\n");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值