中缀表达式转后缀表达式(详解)

**中缀表达式转后缀表达式的一般步骤如下:
1:创建一个空的栈和一个空的输出列表。
2:从左到右扫描中缀表达式的每个字符。
3:如果当前字符是操作数,则直接将其加入到输出列表中。
4:如果当前字符是运算符,比较其与栈顶运算符的优先级:

  1. a. 如果栈为空或栈顶运算符是左括号"(“,则直接将当前运算符入栈。
    b. 如果当前运算符的优先级高于栈顶运算符的优先级,则将当前运算符入栈。
    c. 如果当前运算符的优先级低于或等于栈顶运算符的优先级,则将栈顶运算符弹出并加入到输出 列表中,
    直到栈为空或栈顶运算符的优先级低于当前运算符的优先级,然后将当前运算符入栈。
    d. 如果当前字符是右括号”)“,则依次弹出栈中的运算符并加入到输出列表中,
    直到遇到左括号”("为止,此时将左括号出栈且不加入输出列表。

    5:扫描完整个中缀表达式后,将栈中剩余的运算符依次弹出并加入到输出列表中。
    6:输出列表即为转换后的后缀表达式。
    举个例子:
    中缀表达式:2 + 3 * (4 - 1)
    转换为后缀表达式:2 3 4 1 - * +
    具体实现需要根据编程语言和数据结构来进行操作。
    **
    在这里插入图片描述

项目结构
在这里插入图片描述项目头文件结构QueueStorage.h
在这里插入图片描述项目头文件代码

#ifndef LINKSTACK_H
#define LINKSTACK_H
#include <stdio.h>
#include <stdlib.h>
// 链式栈的节点
typedef struct LINKNODE {struct LINKNODE* next;
}LinkNode;
// 链式栈
typedef struct LINKSTACK {LinkNode head;int size;}LinkStack;// 初始化函数
LinkStack* Init_LinkStack();
// 入栈
void Push_LinkStack(LinkStack* stack, LinkNode* data);
// 出栈
void Pop_LinkStack(LinkStack* stack);
// 返回栈顶元素
LinkNode* TopLinkStack(LinkStack* stack);
// 返回栈元素的个数
int Size_LinkStack(LinkStack* stack);
// 清空栈
void Clear_LinkStack(LinkStack* stack);
// 销毁栈
void FreeSpace_LinkStack(LinkStack* stack);
#endif

项目cpp文件QueueStorage.cpp
在这里插入图片描述项目cpp文件代码QueueStorage.cpp

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <string.h>
#include "QueueStorage.h"// 初始化函数
LinkStack* Init_LinkStack() {LinkStack* stack = (LinkStack*)malloc(sizeof(LinkStack));stack->head.next = NULL;stack->size = 0;return stack;
};
// 入栈
void Push_LinkStack(LinkStack* stack, LinkNode* data) {if (stack == NULL) {return;}if (data == NULL) {return;}// 入栈data->next = stack->head.next;stack->head.next = data;stack->size++;
};
// 出栈
void Pop_LinkStack(LinkStack* stack) {if (stack == NULL) {return;}if (stack->size == 0) {return;}// 第一个有效节点LinkNode* pNext = stack->head.next;stack->head.next = pNext->next;stack->size--;};
// 返回栈顶元素
LinkNode* TopLinkStack(LinkStack* stack) {if (stack == NULL) {return NULL;}if (stack->size == 0) {return NULL;}// 返回栈顶元素return stack->head.next;
};// 返回栈元素的个数
int Size_LinkStack(LinkStack* stack) {if (stack == NULL) {return -1;}return stack->size;
};
// 清空栈
void Clear_LinkStack(LinkStack* stack) {if (stack == NULL) {return;}// 清空栈stack->head.next = NULL;stack->size = 0;};
// 销毁栈
void FreeSpace_LinkStack(LinkStack* stack) {if (stack == NULL) {return;}free(stack);
};

项目主文件截图
在这里插入图片描述项目主文件代码main.cpp

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <string.h>
#include "QueueStorage.h"int IsNumber(char c) {return c >= '0' && c <= '9';
}
// 判断是不是左括号
int IsLeft(char c) {return c == '(';
}
// 判断是不是右括号
int IsRight(char c) {return c == ')';
}
// 判断是不是运算符号
int IsOperator(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 {LinkNode node;char* p;}MyChar;// 对于数字的操作
void NumberOperate(char* p) {printf("%c", *p);
}
// 创建MyChar
MyChar* CreateMyChar(char* p) {MyChar* mychar = (MyChar*)malloc(sizeof(MyChar));mychar->p = p;return mychar;
}// 对于左括号的操作
void LeftOperate(LinkStack* stack,char* p) {Push_LinkStack(stack, (LinkNode*)CreateMyChar(p));
}
// 对于右括号的操作
void RightOperate(LinkStack* stack) {// 判断栈中是否存在元素while (Size_LinkStack(stack) > 0) {// 将里面的元素取出MyChar* mychar = (MyChar*)TopLinkStack(stack);// 如果匹配到左括号的话就弹出if (IsLeft(*(mychar->p))) {Pop_LinkStack(stack);break;}// 输出printf("%c", *(mychar->p));// 弹出Pop_LinkStack(stack);// 释放内存free(mychar);}
}
// 运算符号的操作
void OperatorOperate(LinkStack* stack, char* p) {// 取出栈顶符号MyChar* mychar = (MyChar*)TopLinkStack(stack);if (mychar == NULL) {Push_LinkStack(stack, (LinkNode*)CreateMyChar(p));return;}// 如果栈顶优先级低于符号的优先级直接入栈if (GetPriority(*(mychar->p) < GetPriority(*p))) {Push_LinkStack(stack,(LinkNode*)CreateMyChar(p));return;}else {// 如果栈顶符号优先级不低while (Size_LinkStack(stack) > 0) {MyChar* mychar2 = (MyChar*)TopLinkStack(stack);// 如果优先级低当前的符号入栈if (GetPriority(*(mychar2->p)) < GetPriority(*p)) {Push_LinkStack(stack, (LinkNode*)CreateMyChar(p));break;}// 输出printf("%c ", *(mychar2->p));// 弹出Pop_LinkStack(stack);// 释放free(mychar2);}}
}int main()
{/*栈的应用:中缀表达式转后缀表达式*/char* str = (char *)"8 + (3 - 1) * 5";// 遍历字符串char* p = str;// 创建栈LinkStack* stack = Init_LinkStack();while (*p != '\0') {// 判断是否数数字,如果是数字的话直接输出if (IsNumber(*p)) {NumberOperate(p);}// 判断是不是左括号,如果是左括号直接进栈if (IsLeft(*p)) {LeftOperate(stack,p);}// 如果是右括号的话将栈顶符号弹出知道匹配到左括号为止if (IsRight(*p)) {RightOperate(stack);}// 如果是运算符号的话if (IsOperator(*p)) {OperatorOperate(stack,p);}p++;}//将栈中剩余的元素弹出并输出while (Size_LinkStack(stack) > 0) {MyChar* mychar = (MyChar*)TopLinkStack(stack);printf("%c", *(mychar->p));Pop_LinkStack(stack);free(mychar);}system("pause");return 0;
}

修改运行界面
在这里插入图片描述在这里插入图片描述在这里插入图片描述项目运行结果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/247382.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

dll动态链接库【C#】

1说明: 在C#中,dll是添加 【类库】生成的。 2添加C#的dll: (1)在VS中新建一个Windows应用程序项目,并命名为TransferDll。 (2)打开Windows窗体设计器,从工具箱中为窗体添加相应的控件。 (3)在该应用程序的“解决方案资源管理”中的“引用”文件上单击鼠标右键, 在…

10、外观模式(Facade Pattern,不常用)

外观模式&#xff08;Facade Pattern&#xff09;也叫作门面模式&#xff0c;通过一个门面&#xff08;Facade&#xff09;向客户端提供一个访问系统的统一接口&#xff0c;客户端无须关心和知晓系统内部各子模块&#xff08;系统&#xff09;之间的复杂关系&#xff0c;其主要…

STM32通用定时器

本文实践&#xff1a;实现通过TIM14_CH1输出PWM&#xff0c;外部显示为呼吸灯。 通用定时器简介 拥有TIM2~TIM5、TIM9~TIM14 一共10个定时器&#xff0c;具有4路独立通道&#xff0c;可用于输入捕获、输出比 较&#xff0c;同时包含了基本定时去的所有功能。 通用定时器的结…

【Linux | 编程实践】防火墙 (网络无法访问)解决方案 Vim常用快捷键命令

&#x1f935;‍♂️ 个人主页: AI_magician &#x1f4e1;主页地址&#xff1a; 作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域优质创作者。 &#x1f468;‍&#x1f4bb;景愿&#xff1a;旨在于能和更多的热爱计算机的伙伴一起成长&#xff01;&#xff01;&…

字符串函数strlen的用法详解及其相关题目

strlne函数的使用 一.strlen函数的声明二.strlen函数的头文件三.相关题目代码1代码2题目1题目2题目3题目4题目5题目6 一.strlen函数的声明 size_t strlen ( const char * str );二.strlen函数的头文件 使用strlen函数我们需要使用以下头文件 #include <string.h>三.相…

景联文科技解读《2023人工智能基础数据服务产业发展白皮书》,助力解决数据标注挑战

前段时间&#xff0c;国家工业信息安全发展研究中心发布《2023人工智能基础数据服务产业发展白皮书》&#xff08;以下简称“白皮书”&#xff09;。 《白皮书》指出&#xff0c;2022年&#xff0c;中国人工智能基础数据服务产业的市场规模为45亿元&#xff0c;预计今年将达到5…

一篇解析context_switch进程切换(针对ARM体系架构)

一. 概述 在最近初学ebpf时&#xff0c;使用到了挂载点finish_task_switch统计内核线程的运行时间&#xff0c;遂进入内核源码对其进行学习分析。 finish_task_switch在context_switch被调用&#xff0c;其功能是完成进程切换的收尾工作&#xff0c;比如地址空间的清理。而co…

pycharm打断点调试

在PyCharm中使用断点调试可以帮助逐行执行代码并查看变量的值&#xff0c;以便更好地理解程序的执行过程。以下是在PyCharm中设置断点和使用调试功能的步骤和注意事项&#xff1a; 步骤&#xff1a; 打开PyCharm并打开要调试的项目。找到要设置断点的代码行。您可以在行号区…

大数据技术学习笔记(四)—— HDFS

目录 1 HDFS 概述1.1 HDFS 背景与定义1.2 HDFS 优缺点1.3 HDFS 组成架构1.4 HDFS 文件块大小 2 HDFS的shell操作2.1 上传2.2 下载2.3 HDFS直接操作 3 HDFS的客户端操作3.1 Windows 环境准备3.2 获取 HDFS 的客户端连接对象3.3 HDFS文件上传3.4 HDFS文件下载3.5 HDFS删除文件和目…

ROS2 galactic生成的bag包里的MarkerArray在humble下播放不正常

近期发现ROS2 galactic下生成的bag包在humble下回放时使用rviz可视化&#xff0c;bag里的点云可以正常看到&#xff0c;但是使用Marker和MarkerArray画的box却死活看不到&#xff0c;感觉很纳闷&#xff0c;看网上有人报告说foxy下生成的bag包在galactic下播放会报SQL错误&…

Oracle 中换行chr(10)、回车chr(13)

一、前言 chr(n)&#xff1a;返回 ascii 值对应的字符。 ascii(char)&#xff1a;返回字符 char对应的ascii 值。 chr(n) 和 ascii(char) 作用刚好是相反的。 SQL> select chr(65) from dual; 控制台显示&#xff1a;ASQL> select ascii(A) from dual; 控制台显示&am…

【C++】开源:Boost进程间通信库InterProcess配置使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍Boost进程间通信库InterProcess配置使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一…