中缀表达式转后缀表达式

简介: 本文提供了一个C语言程序,用于将中缀表达式转换为后缀表达式,并计算后缀表达式的结果,包括处理运算符优先级、括号匹配以及基本的四则运算。

中缀表达式转后缀表达式并计算结果

1. 话不多说,先上镇楼图
在这里插入图片描述
2.要实现中缀到后缀的转换

1.如果是数字,直接存入缓冲数组
2.如果是运算符直接入栈(注意优先级)
 3.当前入栈字符优先级高于栈顶字符优先级(或者当前栈为空)则直接入栈
4.当前入栈字符优先级低于栈顶字符优先级,则需要出栈栈顶元素(出栈的字符存入缓冲数组),直到当前入栈字符优先级高于栈顶字符优先级
5.左括号"(" ,在栈外默认优先级最高,入栈后默认优先级最低
6.遇到右括号")",则依次弹出栈顶元素直至弹出左括号")"

3.实现前的一些准备

1.创建一个全局缓冲字符数组用来存储转换过程中的字符以及数字

char buffer[SIZE] = { 0 };   //存储缓冲

2.创建一个让字符存入缓冲的函数Put

//字符存入
void Put(char ch)
{
    static int index = 0; //静态变量
    buffer[index++] = ch;
}

3.设置运算符的优先级

//设置优先级
int Priority(char ch)
{
    int ret = 0;
    switch (ch)
    {
    case '+':
    case '-':
        ret = 1;
        break;
    case '*':
    case '/':
        ret = 2;
        break;
    default:
        break;
    }
    return ret;
}

4.判断是否是左括号,右括号

//是左括号
int isLeft(char ch)
{
    return ch == '(';
}
//是右括号
int isRight(char ch)
{
    return ch == ')';
}

5.判断是否是运算符

//是否是运算符
int isOperator(char ch)
{
    return (ch == '+' || ch == '-' || ch == '*' || ch == '/');
}

6.判断是否是数字

//是否是数字
int isNumber(char ch)
{
    return (ch >= '0' && ch <= '9');
}

7.实现中缀向后缀的转换

//中缀转后缀  正确返回Correct  错误返回Error
int transForm(const char* str)
{
    //创建一个数组栈
    char stack[SIZE];
    //初始化栈中数据
    memset(stack, 0, sizeof(char)*SIZE);
    int top = -1;
    //遍历字符
    while (*str)
    {
        //判断是否为数字,是数字直接存入buffer
        if (isNumber(*str))
        {
            Put(*str);  //存入buffer
        }
        else if (isOperator(*str))   //判断是否为运算符
        {
//比较栈顶字符与入栈字符的优先级  需要弹出所有的栈顶元素大于入栈字符的元素
//top!=-1 表示栈不为空
            while (top != -1 && Priority((char)stack[top]) >= Priority(*str))
            {
                    //1.入栈字符优先级低于栈顶元素,出栈栈顶元素存入buffer
                    Put((char)stack[top--]);
            }
            //2.入栈字符优先级高于栈顶元素直接入栈或者 空栈直接入栈
            stack[++top] = *str;  //入栈
        }
        else if (isLeft(*str))   //左括号 直接入栈
        {
            stack[++top] = *str;  //入栈
        }
        else if (isRight(*str))  //右括号
        {
            //栈空返回Error
            if (top == -1)
            {
                printf("栈中数据读取错误!\n");
                return Error;
            }
            //栈顶元素不是左括号
            while (!isLeft((char)stack[top]))
            {
                //不是左括号出栈栈顶元素 并保存至缓冲数组中
                Put((char)stack[top--]);
                //没有找到
                //没有对应的左括号与右括号匹配
                if (top == -1)
                {
                    printf("未找到左括号!\n");
                    return Error;
                }
            }
            //找到左括号将左括号弹出
            stack[top--];
        }
        else
        {
            printf("有不能识别的字符!\n");
            return Error;
        }
        str++;
    }
    //遍历结束,弹出栈中的剩下的所有元素
    if (*str == '\0')
    {
        while (top !=-1)
        {
        //如果还有左括号未跟右括号匹配则返回Error
            if (isLeft((char)stack[top]))
            {
                printf("还存在没有匹配的\"(\"没有\")\"匹配\n");
                return Error;
            }
            //出栈栈中元素并存入缓冲
            Put((char)stack[top--]);
        }
    }
    else
    {
        printf("遍历没有完成!\n");
            return Error;
    }
    return Correct;
}

8.如何实现后缀表达式的计算??

  1. 遍历后缀表达式
  2. 如果是数字就入栈
  3. 如果是运算符就出栈栈中的两个数字(左操作数与右操作数)做运算
  4. 计算结果入栈继续上述操作,直至栈空

9.实现后缀表达式的计算

//传入字符并返回运算结果
int express(int left, int right, char op)
{
    switch (op)
    {
    case '+':
        return left + right;
    case '-':
        return left - right;
    case '*':
        return left * right;
    case '/':
        return left / right;
    default:
        break;
    }
    return -1;
}
//后缀表达式的计算
int calculatePosture(const char* str)
{
    //创建一个空栈
    int stack[SIZE] = { 0 };
    int top = -1;
    //保存计算后的结果
    int ret = 0;
    //遍历字符串
    while (*str)
    {
        //如果是数字字符直接入栈
        if (isNumber(*str))
        {
            //将字符转换为数字后再入栈
            stack[++top] = *str - '0';
        }
        //如果是运算符
        else if (isOperator(*str))
        {
        //栈不为空
            if (top == -1)
            {
                printf("栈中数据错误!\n");
                break;
            }
            //出栈栈中数字
            int left = stack[top--];
            int right = stack[top--];
            //做运算
            ret = express(left, right, *str);
            //运算结果入栈
            stack[++top] = ret;
        }
        else
        {
            printf("后缀表达式有误!\n");
            break;
        }
        //指针偏移
        str++;
        //遍历结束并且栈中仅有一个元素
        //返回栈中计算结果
        if (!(*str) && top == 0)
            return ret;
    } 
}

10.整体代码

#include<stdio.h>
#include<stdlib.h>
#define SIZE 1024
#define Error 0
#define Correct 1

char buffer[SIZE] = { 0 };   //存储缓冲
//字符存入
void Put(char ch)
{
    static int index = 0; //静态变量
    buffer[index++] = ch;
}
//设置优先级
int Priority(char ch)
{
    int ret = 0;
    switch (ch)
    {
    case '+':
    case '-':
        ret = 1;
        break;
    case '*':
    case '/':
        ret = 2;
        break;
    default:
        break;
    }
    return ret;
}
//是左括号
int isLeft(char ch)
{
    return ch == '(';
}
//是右括号
int isRight(char ch)
{
    return ch == ')';
}
//是否是运算符
int isOperator(char ch)
{
    return (ch == '+' || ch == '-' || ch == '*' || ch == '/');
}
//是否是数字
int isNumber(char ch)
{
    return (ch >= '0' && ch <= '9');
}
//中缀转后缀  正确返回Correct  错误返回Error
int transForm(const char* str)
{
    //创建一个栈
    char stack[SIZE];
    memset(stack, 0, sizeof(char)*SIZE);
    int top = -1;
    //遍历字符
    while (*str)
    {
        //判断是否为数字,是数字直接存入buffer
        if (isNumber(*str))
        {
            Put(*str);  //存入buffer
        }
        else if (isOperator(*str))   //判断是否为运算符
        {
            //比较栈顶元素与新字符的优先级  需要弹出所有的栈顶元素大于新字符的元素
            while (top != -1 && Priority((char)stack[top]) >= Priority(*str))
            {
            //1.新字符优先级低于栈顶元素,出栈栈顶元素存入buffer
                    Put((char)stack[top--]);
            }
            //2.新字符优先级高于栈顶元素直接入栈或者 空栈
            stack[++top] = *str;  //入栈
        }
        else if (isLeft(*str))   //左括号 入栈
        {
            stack[++top] = *str;  //入栈
        }
        else if (isRight(*str))  //右括号
        {
            //判断栈顶是否为左括号,不是就弹出,直到找到左括号
            if (top == -1)
            {
                printf("栈中数据读取错误!\n");
                return Error;
            }
            while (!isLeft((char)stack[top]))
            {
                //不是左括号出栈 并保存
                Put((char)stack[top--]);
                //没有找到
                if (top == -1)
                {
                    printf("未找到左括号!\n");
                    return Error;
                }
            }
            //找到左括号弹出
            stack[top--];
        }
        else
        {
            printf("有不能识别的字符!\n");
            return Error;
        }
        str++;
    }
    //遍历结束,弹出栈中的所有元素
    if (*str == '\0')
    {
        while (top !=-1)
        {
            if (isLeft((char)stack[top]))
            {
                printf("还存在没有匹配的\"(\"没有\")\"匹配\n");
                return Error;
            }
            Put((char)stack[top--]);
        }
    }
    else
    {
        printf("遍历没有完成!\n");
            return Error;
    }
    return Correct;
}

//后缀表达式的计算
int express(int left, int right, char op)
{
    switch (op)
    {
    case '+':
        return left + right;
    case '-':
        return left - right;
    case '*':
        return left * right;
    case '/':
        return left / right;
    default:
        break;
    }
    return -1;
}
int calculatePosture(const char* str)
{
    //创建一个空栈
    int stack[SIZE] = { 0 };
    int top = -1;
    //保存计算后的结果
    int ret = 0;
    //遍历字符串
    while (*str)
    {
        //如果是数字直接入栈
        if (isNumber(*str))
        {
            //入栈是将字符转换为数字
            stack[++top] = *str - '0';
        }
        //如果是运算符
        else if (isOperator(*str))
        {
            if (top == -1)
            {
                printf("栈中数据错误!\n");
                break;
            }
            //出栈数字
            int left = stack[top--];
            int right = stack[top--];
            //做运算
            ret = express(left, right, *str);
            //运算结果入栈
            stack[++top] = ret;
        }
        else
        {
            printf("后缀表达式有误!\n");
            break;
        }
        //指针偏移
        str++;
        //遍历结束并且栈中仅有一个元素
        //返回栈中计算结果
        if (!(*str) && top == 0)
            return ret;
    } 
}
int main()
{
    system("color F0");
    char str[SIZE] = { 0 };
    printf("请您输入您想转换的中缀表达式!\n");
    scanf("%s", str);
    if (transForm(str) == Error)
    {
        printf("出现错误,转换失败!\n");
    }
    else
        printf("转换后的后缀表达式为: %s\n", buffer);
    //后缀表达式的计算
    int answer = calculatePosture(buffer);
    printf("运算结果为: %d\n", answer);

    system("pause");
    return 0;
}

11.运行示例
okok

相关文章
|
机器学习/深度学习 数据可视化 PyTorch
【PyTorch】TensorBoard基本使用
【PyTorch】TensorBoard基本使用
1554 0
mAP@0.5与mAP@0.50.95的含义,YOLO
mAP@0.5与mAP@0.50.95的含义,YOLO
3357 0
|
缓存 网络协议 Linux
计算机网络——Wireshark软件使用与协议分析(ARP协议、IP与ICMP分析)
Wireshark软件使用与协议分析 ARP协议分析 使用 Wireshark 抓取局域网的数据包并进行分析: 1. 学习 Wireshark 基本操作:重点掌握捕获过滤器和显示过滤器。 2. 观察 MAC 地址:了解 MAC 地址的组成,辨识 MAC 地址类型。 3. 分析以太网帧结构:观察以太网帧的首部和尾部,了解数据封装成帧的原理。 4. 分析 ARP 协议:抓取 ARP 请求和应答报文,分析其工作过程。 IP与ICMP分析 启动 Wireshark,捕捉网络命令执行过程中本机接受和发送的数据报。
3248 0
计算机网络——Wireshark软件使用与协议分析(ARP协议、IP与ICMP分析)
|
存储 传感器 定位技术
【NI Multisim 14.0原理图设计基础——元器件分类】
一、元器件分类 NI Multisim 14.0不仅提供了数量众多的元器件符号图形,而且还设计了元器件的模型,并分门类地存储在各个元器件库中。下面按照元器件库的命名不同详细介绍常用的元器件。 1.电源库 单击“元器件”工具栏中的“放置源” 按钮,Sources 库的“系列”栏包括以下几种,如图所示: 电源(POWER-SOURCES):包括常用的交直流电源、数字地、地线、星形或三角形连接的三相电源、VCC、VDD、VEE、VSS 电压源,其元器件”栏下内容如图所示: 电压信号源(SIGNAL-VOLTAG…):包括交流电压、时钟电压、脉冲电压、指数电压、FM、AM等多种形式的电压信号,其“元器
22350 4
【NI Multisim 14.0原理图设计基础——元器件分类】
|
10月前
|
安全 API UED
2026 年起 WhatsApp 消息计费将调整!企业必看!
WhatsApp 将于 2026 年 1 月起调整全球消息计费规则:法国、埃及的营销类消息价格大幅下调(降幅近40%),美加的验证与通知类消息也小幅降价;但印度 Marketing 消息价格上涨约10%。出海企业需根据区域成本变化,重新评估通信预算与触达策略,避免隐性成本累积。
1533 0
|
存储 监控 安全
如何精准高效做好网站安全防护?一文解读
如何精准高效做好网站安全防护?一文解读
479 4
中缀表达式转后缀表达式(逆波兰式)
中缀表达式转后缀表达式(逆波兰式)
1832 0
|
前端开发 容器
CSS 中几种常用的换行方法
CSS 中几种常用的换行方法
854 2
|
存储 监控 关系型数据库
如何升级MySQL版本?
如何升级MySQL版本?
1188 2
【数据结构】判断二叉树是否是完全二叉树
【数据结构】判断二叉树是否是完全二叉树
935 5