数据结构栈——中缀表达式转后缀表达式

server/2024/11/14 23:05:47/

    我们平常所用的标准四则运算表达式,如9+(3-1)*3+10/2叫做中缀表达式,后缀表达式为9 3 1 - 3 * + 10 2 / +,而后缀表达式更容易被计算机所理解计算,我们需要利用栈将中缀表达式转成后缀表达式。

    规则:从左到右遍历中缀表达式中的每个数字和符号,遇到数字就输出,遇到符号,判断与栈顶符号的优先级,是右括号或优先级不高于栈顶符号,将栈顶元素依次出栈并输出,并将当前符号进栈,直到输出后缀表达式为止。

    注:括号在后缀表达式中不出现,但括号在处理过程中是需要进栈的,当匹配到右括号时,将左括号后面的符号全部输出。

题目:

假定运算符集合为{ +、-、*、/、(、)},利用栈将输入的中缀表达式转换成等价的后缀表达式,并输出。

输入格式:

输入一个字符串表示的中缀表达式(以“#”结束),其中每个操作数用一个小写字母表示。

输出格式:

将对应的后缀表达式输出。

输入样例:

a+b-a*((c+d)/e-f)+g#

输出样例:

ab+acd+e/f-*-g+

代码如下:

#include <stdio.h>
#include <ctype.h>#define MAX 100// 定义栈的结构体
typedef struct {char data[MAX];  //数组存储字符int top;         //表示栈顶的位置
} Stack;//栈初始化,将栈顶设为1,表示栈为空
void InitStack(Stack* s) {s->top = -1;
}//判空
int IsEmpty(Stack* s) {return s->top == -1;
}//入栈
int Push(Stack* s, char c) {if (s->top < MAX - 1) {s->data[++(s->top)] = c;  //先压入,top+1return 1;}return 0;
}//出栈
int Pop(Stack* s, char* c) {if (!IsEmpty(s)) {*c = s->data[(s->top)--];return 1;}return 0;
}//获取栈顶元素
char GetTop(Stack* s) {if (!IsEmpty(s)) {return s->data[s->top];}return '#';  // 当栈为空时返回特殊符号
}// 定义运算符的优先级
int Priority(char op) {if (op == '*' || op == '/') {return 2;} else if (op == '+' || op == '-') {return 1;} else {return 0;  // '(' 的优先级最低}
}// 中缀转后缀的主函数
void InfixToPostfix(char* expr) {Stack s;InitStack(&s);char result[MAX];  // 用于存储后缀表达式int k = 0;for (int i = 0; expr[i] != '#'; i++) {char c = expr[i];if (islower(c)) {result[k++] = c;  // 如果是操作数,直接加入结果} else if (c == '(') {Push(&s, c);  // 左括号直接入栈} else if (c == ')') {char top;while (Pop(&s, &top) && top != '(') {result[k++] = top;  // 遇到右括号,弹出栈直到遇到左括号}} else {  // 是运算符//栈顶运算符优先级>=当前运算符while (!IsEmpty(&s) && Priority(GetTop(&s)) >= Priority(c)) {char top;Pop(&s, &top);result[k++] = top;  // 如果当前运算符优先级不高于栈顶运算符,弹出栈顶运算符}Push(&s, c);  // 当前运算符入栈}}// 把栈中剩余的运算符弹出char top;      //存储从栈中弹出的运算符while (Pop(&s, &top)) {  //当栈不为空时,不断弹出栈顶元素result[k++] = top;   //先将top添加到结果中,并将k增加}result[k] = '\0';  // 在字符串末尾添加了一个空字符printf("%s\n", result);  // 输出后缀表达式
}int main() {char expr[MAX];scanf("%s", expr);  // 输入中缀表达式InfixToPostfix(expr);  // 转换为后缀表达式并输出return 0;
}


http://www.ppmy.cn/server/121772.html

相关文章

毕设基于SSM+Vue3实现设备维修管理系统四:后台框架及基础增删改查功能实现

本章介绍后端基础框架及基础的增删改查功能实现&#xff0c;创建基础的dao、service即controller层相关的基类&#xff0c;并实现基础的增删改查相关功能。 源码下载&#xff1a;点击下载 讲解视频&#xff1a; SMMVUE3实现设备维修管理系统毕设&#xff1a;后端框架搭建及表外…

Vue 组件通信指南:Props 和 $emit,Vuex(状态管理),EventBus(事件总线),Provide/Inject(依赖注入)

引言 在 Vue 中&#xff0c;组件是构建应用的基本单元&#xff0c;而组件通信则是构建复杂应用的关键。组件通信是指在不同的 Vue 组件之间传递数据、交互和共享状态的过程&#xff0c;它在构建大型应用和组织代码方面起着至关重要的作用。 在开发过程中&#xff0c;我们经常…

智算中心动环监控:构建高效、安全的数字基础设施@卓振思众

在当今快速发展的数字经济时代&#xff0c;智算中心作为人工智能和大数据技术的核心支撑设施&#xff0c;正日益成为各行业实现智能化转型的重要基石。为了确保这些高性能计算环境的安全与稳定&#xff0c;卓振思众动环监控应运而生&#xff0c;成为智算中心管理的重要组成部分…

显示屏显示缺陷检测系统源码分享

显示屏显示缺陷检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Comput…

C++之STL—List 链表

双向链表 链表的组成&#xff1a;链表由一系列**结点**组成 结点的组成&#xff1a;一个是存储数据元素的**数据域**&#xff0c;另一个是存储下一个结点地址的**指针域** STL中的链表是一个双向循环链表 构造函数 List 赋值和交换 容器大小操作 - 判断是否为空 --- empty - …

vue3ScrollSeamless滚动如何给子元素添加点击事件:事件委托

页面布局如上截图 下面是方法 function parentClick(e) {if (e.target.tagName A) {router.push({path: /noticeDetails,query: {id: e.target.dataset.eid}});} }使用的时候&#xff0c;可以打印一下方法里面的e&#xff0c;加深理解

vue3怎么使用Vue.prototype.$loading来实现定义全局的变量和函数

vue2中我们可以在main.js里面通过Vue.prototype.$loading"ddddd"来定义全局变量。其他页面直接使用this.$loading就可以获取值。 vue3中也想实在这个功能怎么办&#xff1f; import App from "./App.vue"; import { createApp } from "vue"; co…

Altium Designer(AD)百度云下载与安装(附安装步骤)

在我们日常使用当中&#xff0c;Altium designer常常也被简称为AD&#xff0c;是一款一体化的电子产品开发系统软件&#xff0c;主要运行在Windows操作系统上。 我们通过Altium designer把原理图设计、电路仿真、PCB绘制编辑、拓扑逻辑自动布线、信号完整性分析和设计输出等技…