数据结构-栈应用之逆波兰表达式(后缀表达式)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zwx19921215/article/details/83305964

逆波兰表达式含义我就不做赘述了,摘自百科上的一段话:

逆波兰表达式又叫做后缀表达式。在通常的表达式中,二元运算符总是置于与之相关的两个运算对象之间,这种表示法也称为中缀表示。波兰逻辑学家J.Lukasiewicz于1929年提出了另一种表示表达式的方法,按此方法,每一运算符都置于其运算对象之后,故称为后缀表示。
逆波兰表达式,它的语法规定,表达式必须以逆波兰表达式的方式给出。逆波兰表达式又叫做后缀表达式。这个知识点在数据结构和编译原理这两门课程中都有介绍,下面是一些例子:
正常的表达式 逆波兰表达式
a+b ---> a,b,+
a+(b-c) ---> a,b,c,-,+
a+(b-c)*d ---> a,b,c,-,d,*,+
a+d*(b-c)--->a,d,b,c,-,*,+
a=1+3 ---> a,1,3,+,=

用途

逆波兰表达式是一种十分有用的表达式,它将复杂表达式转换为可以依靠简单的操作得到计算结果的表达式。例如(a+b)*(c+d)转换为ab+cd+*


优势

它的优势在于只用两种简单操作,入栈和出栈就可以搞定任何普通表达式的运算。其运算方式如下:
如果当前字符为变量或者为数字,则压栈,如果是运算符,则将栈顶两个元素弹出作相应运算,结果再入栈,最后当表达式扫描完后,栈里的就是结果。

以上红线为划重点,如果没理解这句话的意思,那么接下来的代码就不用看了(无奈~~)

//
// Created by Administrator on 2018/5/28.
//

//逆波兰表达式(后缀表达式)

#include "stdio.h"
#include "stdlib.h"
#include "string.h"

#define ElementType int
#define MaxSize 20

//定义栈的结构体
typedef struct {
    ElementType *top;//栈顶指针(这里定义为指向栈顶元素的下一个位置,即为空)
    ElementType *base;//栈底指针
    int stackSize;//栈的容量
} Stack;

/**
 *  初始化栈
 * @param s
 */
void InitStack(Stack *s) {
    //初始化分配栈的总空间
    s->base = (ElementType *) malloc(MaxSize * sizeof(ElementType));
    if (!s->base) {
        //分配失败
        printf("初始化分配空间失败!");
        exit(0);
    }
    s->top = s->base;
    s->stackSize = MaxSize;
}

/**
 * 入栈
 * @param s 栈
 * @param e 入栈元素
 */
void Push(Stack *s, ElementType e) {
    //判断栈是否已满
    if (s->top - s->base >= s->stackSize) {
        //栈已满
        //处理方式1.递增空间 2.退出
        printf("栈已满~\n");
        exit(0);
    }
    *(s->top) = e; //赋值
    s->top++;
}

/**
 * 出栈
 * @param s 栈
 * @return
 */
ElementType Pop(Stack *s) {
    //判断栈是否为空
    if (s->base == s->top) {
        //栈为空
        //printf("\n不好意思,栈目前为空~\n");
        return -1;
    }
    s->top--;
    ElementType e = *(s->top);//取值,并不是取地址
    return e;
}

/**
 * 栈当前容量
 * @param s
 * @return
 */
ElementType GetLen(Stack s) {
    int len = (s.top - s.base);
    return len;
}

int main() {
    //存在中缀表达式:1+2*(4-3)+6/6
    //转换为后缀表达式:1234-*+66/+
    char exp[] = {'1', '2', '4', '3', '-', '*', '+', '6', '6', '/', '+'};
    Stack stack;
    InitStack(&stack);
    int len = strlen(exp);
    int length = sizeof(exp) / sizeof(exp[0]);
    for (int i = 0; i < length; i++) {
        char p = exp[i];
        int temp;
        ElementType a;
        ElementType b;
        switch (p) {
            case '+':
                a = Pop(&stack);
                b = Pop(&stack);
                temp = b + a;
                Push(&stack, temp);
                break;
            case '-':
                a = Pop(&stack);
                b = Pop(&stack);
                temp = b - a;
                Push(&stack, temp);
                break;
            case '*':
                a = Pop(&stack);
                b = Pop(&stack);
                temp = b * a;
                Push(&stack, temp);
                break;
            case '/':
                a = Pop(&stack);
                b = Pop(&stack);
                if (b == 0) {
                    printf("除数不能为0~\n");
                    return -1;
                }
                temp = b / a;
                Push(&stack, temp);
                break;
            default:
                temp = p - 48;
                Push(&stack, temp);
                break;
        }
    }
    char sum = Pop(&stack);
    printf("\n表达式计算结果 value=%d\n", sum);
}

猜你喜欢

转载自blog.csdn.net/zwx19921215/article/details/83305964