数据结构与算法--1.2栈--中缀表达式转换为后缀表达式

本文介绍了如何将中缀表达式转换为后缀表达式,以1+(2-3)*4+10/5为例,详细展示了转换过程,并提出了转化思路,包括遍历、判断符号优先级和栈操作。最终得到的后缀表达式为1 2 3 - 4 * + 10 5 / +。
摘要由CSDN通过智能技术生成

比如有中缀表达式:1+(2-3)*4+10/5

--> 1+(2 3 -)*4 + 10 / 5

--> 1+ (2 3 - 4 * )+ 10 / 5

--> 1 2 3 - 4 * + 10 / 5

--> 1 2 3 - 4 * + 10 5 / +

转换为后缀表达式为:1 2 3 - 4 * + 10 5 / +

1.转化思路

从左到右遍历中缀表达式的每一个数字和符号,若是数字则直接输出,若是符号了,则判断与其栈顶符号的优先级,是右括号或者优先级低于栈顶符号,则栈顶元素依次出栈并输入,直到遇到左括号或栈空才将最后的+号入栈。

// 栈-后缀表达式.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#define _CRT_SECURE_NO_WARNINGS  //为了避免scanf函数报错
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#define InitSize 20
#define IncrementSize 10
#define MAXBUFFER 10
typedef char ElimentType;
typedef struct
{
    ElimentType* top;
    ElimentType* base;
    int StackSize;
}sqStack;

void InitStack(sqStack* s)
{
    s->base = (ElimentType*)malloc(InitSize * sizeof(ElimentType));
    if (!s->base)
    {
        exit(0);
    }
    s->top = s->base;
    s->StackSize = InitSize;
}void Push(sqStack* s, ElimentType c)
{
    if (s->top - s->base >= s->StackSize)
    {
        s->base = (ElimentType*)realloc(s->base, (s->StackSize + IncrementSize) * sizeof(ElimentType));
        if (!s->base)
        {
            exit(0);
        }
        s->top = s->base + s->StackSize;
        s->StackSize = s->StackSize + IncrementSize;
    }
    *(s->top) = c;
    s->top++;
}
void Pop(sqStack* s, ElimentType* c)
{
    if (s->top == s->base)
    {
        return;
    }
    s->top--;
    *c = *(s->top);
}
int Stacklen(sqStack s)
{
    int len = 0;
    len = s.top - s.base;
    return len;
}


int main()
{

    sqStack s;
    InitStack(&s);
    char c,temp;
    int len;
    printf("请输入一个中缀表达式,以#结束\n");
    scanf("%c", &c);

    while (c != '#')
    {
        while ((c >= '0') && (c <= '9'))
        {
            printf("%c", c);
            scanf("%c", &c);
            if ((c < '0') || (c > '9'))
            {
                printf(" ");
            }
        }
        if (c == ')')  //如果输入的是),需要检验栈里面是否有(, 如果有(,需要将括号里面的运算符弹出
        {
            Pop(&s, &c);
            while (c != '(')
            {
                printf("%c ", c);
                Pop(&s, &c);
            }
        }
        else if((c=='+') || (c=='-')) //关键代码
        {
            temp = c; //临时变量temp用于存放当前的+-运算符
            if (!Stacklen(s)) //如果栈为空,则直接将+-入栈
            {
                Push(&s, c);
            }
            else //栈不为空,判断栈内的优先级
            {
                do 
                {
                    Pop(&s, &c);  //弹出栈顶元素,
                    if (c == '(') //如果栈顶元素是(,则把 ( 入栈
                    {
                        Push(&s, c);                   
                    }
                    else  //如果栈顶元素不是(,那么该栈顶元素肯定就是*/),直接printf
                    {
                        printf("%c ", c); 
                    }
                } while (Stacklen(s) && (c != '(')); //栈为空,且括号内的运算符都pop之后,则退出
               
                Push(&s, temp);//在所有高优先级的运算符弹出来之后,最后把当前的+-入栈
            }
        }
        else if ((c == '*') || (c == '/') || (c == '('))
        {
            Push(&s, c);
        }
        else if (c == '#') //
        {
             break;
        }
        else //种种可能都不是的话,则是用户输入错误
        {
            printf("用户输入错误!\n");
            return -1;
        }
        scanf("%c", &c);
    }
    while (Stacklen(s)) //最后把栈内的元素全部输出
    {
        Pop(&s, &c);
        printf("%c ", c);
    }
    return 0;
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件

 

 

运行结果:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值