• 22、栈的应用-中缀表达式转后缀表达式


    main.c

    #define _CRT_SECURE_NO_WARNING
    
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include"Stack.h"
    
    //判断是不是数字
    int IsNumber(char c) {
        return c >= '0' && c <= '9';
    }
    
    //判断是不是左括号
    int IsLeft(char c) {
        return c == '(';
    }
    
    //判断是不是右括号
    int IsRight(char c) {
        return c == ')';
    }
    
    //判断是不是运算符号
    int IsOperate(char c) {
        return c == '+' || c == '-' || c == '*' || c == '/';
    }
    
    //返回运算符号优先级
    int GetPriority(char c) {
        if (c == '*' || c == '/') {
            return 2;
        }
        if (c == '+' || c == '-') {
            return 1;
        }
        return 0;
    }
    
    typedef struct MYCHAR {
        StackNode node;
        char* p;
    }MyChar;
    
    //数字操作
    void NumberOperate(char* p) {
        printf("%c", *p);
    }
    
    //创建MyChar
    MyChar* CreatMyChar(char* p) {
        MyChar* mychar = (MyChar*)malloc(sizeof(MyChar));
        mychar->p = p;
        return mychar;
    }
    
    //左括号操作
    void LeftOperate(LinkStack* stack,char* p) {
        Push(stack, (StackNode*)CreatMyChar(p));
    }
    
    //右括号操作
    void RightOperate(LinkStack* stack) {
        //先判断栈中有没有元素
        while (StackLength(stack) > 0) {
            MyChar* mychar = (MyChar*)GetTop(stack);
            //如果匹配到左括号,弹出并输出
            if (IsLeft(*(mychar->p))) {
                Pop(stack);
                break;
            }
    
            //输出
            printf("%c", *(mychar->p));
            //弹出
            Pop(stack);
            //释放内存
            free(mychar);
        }
    }
    
    //运算符号的操作
    void OperateOperate(LinkStack* stack, char* p) {
    
        //先取出栈顶符号
        MyChar* mychar = (MyChar*)GetTop(stack);
        if (mychar == NULL) {
            Push(stack, (StackNode*)CreatMyChar(p));
            return;
        }
        //如果栈顶符号优先级低于当前字符的优先级 直接入栈
        if (GetPriority(*(mychar->p)) < GetPriority(*p)) {
            Push(stack, (StackNode*)CreatMyChar(p));
            return;
        }
    
        //如果栈顶符号优先级不低
        else {
            while (StackLength(stack) > 0) {
    
                MyChar* mychar2 = (MyChar*)GetTop(stack);
    
    
                //如果优先级低 当前符号入栈
                if (GetPriority(*(mychar2->p)) < GetPriority(*p)) {
                    Push(stack, (StackNode*)CreatMyChar(p));
                    return;
                }
    
                //输出
                printf("%c",*(mychar2->p));
                //弹出
                Pop(stack);
                //释放
                free(mychar2);
            }
        }
    }
    
    int main() {
    
        char* str = "8+(3-1)*5";//831-5*+
        char* p = str;
    
        //创建栈
        LinkStack* stack = InitStack();
    
    
        while (*p != '') {
    
            if (IsNumber(*p)) {
                NumberOperate(p);
            }
            //如果是左括号,直接进栈
            else if (IsLeft(*p)) {
                LeftOperate(stack, p);
            }
    
            //如果是右括号
            else if (IsRight(*p)) {
                RightOperate(stack);
            }
    
            //如果是运算符号
            else if (IsOperate(*p)) {
                OperateOperate(stack, p);
            }
    
            p++;
        }
    
        while (StackLength(stack)>0) {
            MyChar* mychar = (MyChar*)GetTop(stack);
            printf("%c", *(mychar->p));
            Pop(stack);
            free(mychar);
        }
    
    
        printf("
    ");
        system("pause");
        return 0;
    }

    stack.h

    #ifndef STACK_H
    #define STACK_H
    
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    
    #define OK 1
    #define ERROR 0
    #define TRUE 1
    #define FALSE 0
    
    typedef void* SElemType;
    typedef int Status;
    //初始化结构
    typedef struct StackNode {
        SElemType data;
        struct StackNode* next;
    }StackNode, *LinkStackPtr;
    
    typedef struct LinkStack {
        StackNode* top;
        int count;
    }LinkStack;
    
    
    //初始化操作,建立一个空栈
    LinkStack* InitStack();
    //将栈清空
    void ClearStack(LinkStack *s);
    //销毁
    void DestoryStack(LinkStack *s);
    //若栈为空,返回TRUE,否则返回false
    Status IsEmpty(LinkStack s);
    //若栈存在且非空,返回S的栈顶元素
    void* GetTop(LinkStack *s);
    //插入元素e为新的栈顶元素
    Status Push(LinkStack *s, SElemType e);
    //若栈不空,则删除S的栈顶元素,并返回OK,否则返回ERROR
    Status Pop(LinkStack *s);
    //返回栈S的元素个数
    Status StackLength(LinkStack *s);
    
    //打印
    void PrintfStack(LinkStack *s);
    
    #endif

    stack.c

    #include"Stack.h"
    
    //初始化操作,建立一个空栈
    LinkStack* InitStack() {
        LinkStack *s = (LinkStack*)malloc(sizeof(LinkStack));
        s->count = 0;
        s->top = (StackNode*)malloc(sizeof(StackNode));
        s->top->data = NULL;
        s->top->next = NULL;
        return s;
    }
    //将栈清空
    void ClearStack(LinkStack *s) {
    
    
    }
    //销毁
    void DestoryStack(LinkStack *s) {
        if (s == NULL) {
            return;
        }
        LinkStackPtr p;
        p = s->top;//将栈顶结点赋值给p
        while (p != NULL) {
            LinkStackPtr pNext = p->next;
            free(p);//释放结点p
            p = pNext;
        }
        s->count = 0;
        free(s);
    }
    //若栈为空,返回TRUE,否则返回false
    Status IsEmpty(LinkStack s) {
        if (s.top->next == NULL) {
            return TRUE;
        }
        return FALSE;
    }
    //若栈存在且非空,返回S的栈顶元素
    void* GetTop(LinkStack *s) {
        if (s == NULL) {
            return NULL;
        }
    
        return s->top->data;
    }
    //插入元素e为新的栈顶元素
    Status Push(LinkStack *s, SElemType e) {
        LinkStackPtr a = (LinkStackPtr)malloc(sizeof(StackNode));
        a->data = e;
        a->next = s->top;//把当前的栈顶元素赋给新结点的直接后继
        s->top = a;//将新结点a赋值给栈顶指针
        s->count++;
        return OK;
    }
    //若栈不空,则删除S的栈顶元素,并返回OK,否则返回ERROR
    Status Pop(LinkStack *s) {
        StackNode* p;
        if (IsEmpty(*s)) {
            return ERROR;
        }
        p = s->top;//将栈顶结点赋值给p
    
        s->top = p->next;//使得栈顶指针下移一位,指向后一结点
        free(p);//释放结点p
    
        s->count--;
        return OK;
    }
    //返回栈S的元素个数
    Status StackLength(LinkStack *s) {
    
        int j = s->count;
        return j;
    }
  • 相关阅读:
    [自用] 数论和组合计数类数学相关(定理&证明&板子)
    OI回忆录?
    [UOJ310] 黎明前的巧克力
    [总结] 后缀自动机学习笔记
    [总结] 动态点分治学习笔记
    [HEOI2018] 秘密袭击coat
    [51nod1355] 斐波那契的最小公倍数
    [SRM601] WinterAndSnowmen
    [总结] 二项式反演学习笔记
    [Luogu4705] 玩游戏
  • 原文地址:https://www.cnblogs.com/luanxin/p/9607947.html
Copyright © 2020-2023  润新知