中缀表达式转后缀表达式

原则

  • 遇到数字 :直接输出
  • 遇到运算符 :输出优先级比自己大的运算符,直至遇到(,然后自己入栈
  • 遇到 :直接入栈
  • 遇到 :输出栈顶元素,直至遇到 (

用到 这个数据结构,利用其 后进先出 的性质

转换原因(后缀表达式的优点)

  • 不需要保存括号
  • 对计算机来说运算简单,运算符之间不存在优先级

注意

  • 右括号不入栈
  • 数字不入栈,直接输出。(想保存可自己设置)
  • 若输入的数字 >=10 ,因输入时当作字符串输入,需改动
  • stack 不必自己定义,可用 C++ STL的stack,只需加上 #include <stack> (下面源码里我是用自己定义的)
    常用函数:
    empty() pop() push() size() top()

源码

在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STACK_INIT_SIZE 10
#define STACKINCREMENT 30
#define elemType int

typedef struct sqStack
{
    elemType *base;
    elemType *top;
    int stackSize;
} sqStack, *pStack;

//top指向空格
void initStack(sqStack *s)
{
    s->base = (elemType *)malloc(STACK_INIT_SIZE * sizeof(elemType));
    if (!s->base)
    {
        printf("malloc failure\n");
        exit(-1);
    }
    s->top = s->base;
    s->stackSize = STACK_INIT_SIZE;
}

elemType getTop(pStack s)
{
    if (s->base == s->top)
    {
        printf("The stack is empty !\n");
        exit(-1);
    }
    return *(s->top - 1);
}

void push(pStack s, elemType e)
{
    if (s->top - s->base >= s->stackSize)
    {
        s->base = (elemType *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(elemType));
        if (!s->base)
        {
            printf("realloc failure\n");
            exit(-1);
        }
        s->stackSize += STACKINCREMENT;
    }
    *(s->top) = e;
    s->top++;
}

void pop(pStack s)
{
    if (s->top == s->base)
    {
        printf("The stack is empty !\n");
        exit(-1);
    }
    s->top--;
}

bool isEmpty(pStack s)
{
    if (s->base == s->top)
        return true;
    return false;
}

int main()
{
    //用字符指针输入不定长字符串(中缀表达式),超好用
    char *p;
    p = (char *)malloc(sizeof(char));
    scanf("%s", p);
    int len = strlen(p);

    //初始化空栈
    pStack s = (pStack)malloc(sizeof(pStack));
    initStack(s);

    //遍历字符串
    for (int i = 0; i < len; i++, p++)
    {
        //数字直接输出
        if (*p >= '0' && *p <= '9')
        {
            printf("%c", *p);
        }
        else
            switch (*p)
            {
            //左括号直接入栈
            case '(':
                push(s, *p);
                break;

            //右括号不入栈,输出栈顶元素,直至栈空或遇到左括号,左括号丢弃不输出
            case ')':
                while (!isEmpty(s) && getTop(s) != '(')
                {
                    printf("%c", getTop(s));
                    pop(s);
                }
                if (getTop(s) == '(')
                    pop(s);
                break;

            //一直输出优先级 >= 自己的栈顶元素,直至栈空或遇到左括号,然后自己入栈
            case '*':
            case '/':
                while (!isEmpty(s) && (getTop(s) == '*' || getTop(s) == '/'))
                {
                    printf("%c", getTop(s));
                    pop(s);
                }
                push(s, *p);
                break;
            case '+':
            case '-':
                while (!isEmpty(s) && getTop(s) != '(')
                {
                    printf("%c", getTop(s));
                    pop(s);
                }
                push(s, *p);
                break;
            default:
                break;
            }
    }

    //遍历完若栈不为空,输出
    while (!isEmpty(s))
    {
        printf("%c", getTop(s));
        pop(s);
    }
}


//计算后缀表达式的值
void calculate(char *p)
{
    int len = strlen(p);

    //初始化空栈
    pStack s = (pStack)malloc(sizeof(pStack));
    initStack(s);

    //遍历字符串
    for (int i = 0; i < len; i++, p++)
    {
        //数字直接入栈
        if (*p >= '0' && *p <= '9')
        {
            push(s, (int)(*p - '0'));
        }
        //若是操作符@,弹出栈顶元素a和新的栈顶元素b,执行b @ a,将结果压入栈中
        else
        {
            int b = getTop(s);
            pop(s);
            int a = getTop(s);
            pop(s);
            int temp = 0;
            switch (*p)
            {
            case '+':
                temp = a + b;
                break;
            case '-':
                temp = a - b;
                break;
            case '*':
                temp = a * b;
                break;
            case '/':
                temp = a / b;
                break;
            }
            push(s, temp);
        }
    }
    //最后栈中只剩下一个元素,即表达式的值。
    printf("The result is %d", getTop(s));
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值