栈之中缀表达式转后缀表达式

2023-11-18

题目描述

就是把我们平常写的运算表达式换成另外一种表达式,运算符前面两个数字执行相关操作。用图说明一下:

比如3+2 -> 3 2 +

比如3 + 3 * 2 -> 3 3 2 * +

再比如 3 + (3 * 2 + 2) * 3 ->3 3 2 * 2 + 3 * +

程序设计思路 

 

 

特殊情况:在中间如果遇到(左括号,除非遇到)右括号,否则不弹出,符号依旧入栈处理,然后在遇到)右括号之前的符号,按照上面规矩出入栈并输出,直到遇到左括号截止出栈。当遇到右括号,从栈顶一直到左括号的内容全部依次出栈并输出,左括号出栈不输出。当表达式遍历结束,依次出栈并输出

备注:也就是说当 ( 左括号做栈顶的时候,当成优先级低处理

写栈之括号匹配问题的时候,用的顺序栈处理,这次用链式栈处理

还是老规矩,先把栈做成一个动态库

代码设计

话不多说,直接上代码:

main.c

#include <stdio.h>
#include <stdlib.h>
#include "linkstack.h"


int main()
{
	char str_expre[100] = { '\0' };//输入
	char res_expre[100] = { '\0' };//输出
	//创建栈
	link_stack *stack = create_stack();
	while(scanf("%s",str_expre) != EOF && stack != NULL) {
		int index = 0;
		int cursor = 0;//结果游标
		while(str_expre[index] != '\0') {
			//这里给一个while循环,实现一个数字的拼接,数字单独处理
			if(str_expre[index] >= 0 && str_expre[index] <= '9') {	
				//如果是数字内部直接循环赋值到另外一个数组中去
				while(1) {
					if(str_expre[index] < '0' || str_expre[index] > '9') {
						break;
					}
					res_expre[cursor++] = str_expre[index++];
				}
				//最后赋值过去给数字之间一个空格
				res_expre[cursor++] = ' ';
			}
			if(is_empty(stack)) {
				push_stack(stack,(int)str_expre[index]);
			} else if(!is_empty(stack) && str_expre[index] != '\0') {
				char top_elem = (char)top_stack(stack);
				if(top_elem == '(') {
					//这种情况直接进栈
					push_stack(stack,(int)str_expre[index]);
				} else if(top_elem == '*' && (str_expre[index] == '+' || str_expre[index] == '-')) {
					//这种情况直接依次出栈并且出栈元素不等于(
					while(top_elem != '('){
						res_expre[cursor++] = top_elem;
						res_expre[cursor++] = ' '; 
						pop_stack(stack);
						top_elem = (char)top_stack(stack);
					}
					//出完栈之后,把当前符号入栈
					push_stack(stack,(int)str_expre[index]);	
				} else if((top_elem == '+' || top_elem == '-') && str_expre[index] != ')') {
					//栈顶优先级低,还是直接入栈
					push_stack(stack,(int)str_expre[index]);
				} else if(str_expre[index] == ')') {
					//一直到(,必须要连续出栈,
					while(top_elem != '(') {
						//连续出栈
						res_expre[cursor++] = top_elem;
						res_expre[cursor++] = ' ';//给数字之间一个空格
						pop_stack(stack);
						top_elem = (char)top_stack(stack);
					}
					//‘(’记得出栈
					pop_stack(stack);
				}
			}
			index++;
		}
		//整体循环完毕,把栈里面内容直接输出
		while(!is_empty(stack)) {
			res_expre[cursor++] = (char)top_stack(stack);
			res_expre[cursor++] = ' ';
			pop_stack(stack);
		}
		printf("%s\n",res_expre);
	}
	return 0;
}

编译并查看运行结果:

利用库里面的顺序栈的操作代码

#include <cstdio>
#include <cstdlib>
extern "C" {
	#include <seqstack1.0.h>
}


int main()
{
			t_seq_stack* p_head = create_stack();
			char str[100] = {'\0'};
			char res[100] = {'\0'};
			while(scanf("%s",str) != EOF && p_head != NULL) {
				//遍历整个中缀表达式字符串
				int index = 0;
				int cursor = 0;
				while(str[index] != '\0') {
					//判断是否是数字
					//方便进行拼接
					if(str[index] >= '0' && str[index] <= '9') {
						while(1) {
							//什么时候跳出
							if(str[index] < '0' || str[index] > '9') {
								break;
							}
							res[cursor++] = str[index++];
						}
						//拼接完了之后给一个空格
						res[cursor++] = ' ';
					}
					
					//下面开始放入其他符号
					//这里就走的是不是数字嘛
					if(is_empty(p_head)) {
						//空栈是直接入栈
						//这里面是一个void*类型的指针
						push_stack(p_head,&str[index]);
					}else if(!is_empty(p_head) && str[index] != '\0') {
						//拿到栈顶元素进行比较
						char *top_elem = (char*) top_stack(p_head);
						//如果是左括号直接进栈
						if(str[index] == '(') {
							push_stack(p_head,&str[index]);
						} else if(*top_elem == '*' && (str[index] == '+' || str[index] == '-')) {
						//栈顶优先级高,依次出栈
						//但是出栈元素不等于(
						while(*top_elem != '(') {
							//这里出栈其实就是插入到res数组里面
							res[cursor++] = *top_elem;
							//中间给一个空格
							res[cursor++] = ' ';
							pop_stack(p_head);
							top_elem = (char*)top_stack(p_head);
						}
						//出完栈之后,还要把当前元素入栈
						push_stack(p_head,&str[index]);
						//栈顶优先级低的情况,直接入栈
					} else if((*top_elem == '+' || *top_elem == '-') || str[index] == '*') {
						//栈顶优先级低,还是直接入栈
						push_stack(p_head,&str[index]);
					} else if(str[index] == ')') {
						//连续出栈,直到匹配到左括号
						while(*top_elem != '(') {
							res[cursor++] = *top_elem;
							res[cursor++] = ' ';
							pop_stack(p_head);
							top_elem = (char*)top_stack(p_head);
						}
						//把左括号给出栈
						pop_stack(p_head);
					}
				}
				index++;
			}	
			//整体遍历
			while(!is_empty(p_head)) {
				char *top_elem = (char*)top_stack(p_head);
				//上面循环完之后,把栈里面剩余的内容继续输出
				res[cursor++] = *top_elem;
				res[cursor++] = ' ';
				pop_stack(p_head);
			}
			printf("%s\n",res);
		}
	return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

栈之中缀表达式转后缀表达式 的相关文章

随机推荐

  • windows下anaconda3安装MySQLdb

    本文转自Windows下python3 6 安装MySQLdb 首先需要下载windows版本的mysqlclient 原作者给出了其中一个版本的下载链接 下载之后 放到合适的文件目录中 然后打开anaconda自带的Anaconda Pr
  • java使用switch语句完成输入1~12之间的整数,显示该月份的英语单词及这个月属第几季度。

    1 程序代码如下 package java实训 import java util Scanner public class SJ4 public static void main String args Scanner input new
  • AI Cloud将百花齐放,青云科技已先走了一步

    三年前 国家超级计算济南中心 济南超算 悄悄干了一件大事 投资数十亿元致力于打造一个融HPC超算 传统云计算 以CPU为主 和智算 以GPU为主 为一体的多元算力中心 这就需要一个统一的并且可以对外开放的运维和运营平台 那时还在打磨阶段的青
  • python注释快捷键 引号注释快捷键 注释字体样式调整

    python注释快捷键分为两种 单行注释 单行注释快捷键是CTRL list red green blue yellow white black print list 0 print list 1 print list 2 list red
  • VS E2996 错误过多,导致IntelliSense引擎无法正常工作。其中一些错误可能在编辑器中不可见。代码没有提示

    一 错误的问题描述 二 这个问题导致的后果 后面程序中用到的很多都会显示找不到定义 三 说实话这个问题真的很坑 由于我更换了我程序的工作电脑 我在VS中属性管理器中重新配置了头文件和对应的库目录 但是这里我犯了一个小错误 就是我更换的时候
  • QT开发技巧之QTableWidget设置表头颜色字体

    1 默认的表头和内容背景字体一样不好区别 可以通过qss设置修改表头样式 2 修改后效果如下 qss代码 表格头背景色 QHeaderView section background rgb 128 255 255 font family 宋
  • vue引入阿里图标 Module parse failed: Unexpected character '�' (1:0)

    操作根据文章 https blog csdn net qq 32113629 article details 79740949 在自己跟着试了一下后报错 Module parse failed Unexpected character 1
  • c++享元模式

    享元模式 1 享元模式简介 享元模式在 设计模式 可复用面向对象软件的基础 一书中是这样说的 运用共享技术有效地支持大量细粒度的对象 本质就是对大量细粒度的对象进行共享 不是每个对象都要通过new的方式去创建 而是通过区分对象的内部状态和外
  • 波形图、频谱图和语谱图

    波形图 反映各质点在同一时刻不同位移的曲线 叫做波的图像 也叫做波形图 波形图用于显示测量值为均匀采集的一条或多条曲线 波形图仅绘制单值函数 即在y f x 中 各点沿x轴均匀分布 例如一个随时间变化的波形 波形图可显示包含任意个数据点的曲
  • 消息通知之系统层事件发布相关流程

    前言 Openharmony 3 1Release中存在消息通知的处理 消息通知包括系统层事件发布 消息订阅 消息投递与处理 为了开发者能够熟悉消息的处理流程 本篇文章主要介绍系统层事件发布的相关流程 整体流程 代码流程 发布消息 even
  • c++ queue用法 入门必看 超详细

    1 queue的作用 说到queue 大家一定会想到stack 同样是简单易用的数据结构之一 queue就是队列的意思 像大家日常排队一样 先排的人先用 stack则是相反的 后来的先用 这就有了queue先进先出 stack后进先出的说法
  • 解决表情包乱码

    问题描述 在 Web 应用或移动App中 我们经常需要显示表情符号 但表情符号包含许多非ASCII字符 不能直接在文本中传输 所以通常会转换为HTML实体编码进行传输和存储 如常见的微笑表情 会编码为 但是后续读取网络返回的文本内容时 如果
  • Kafka——集群

    文章目录 集群 1 搭建个集群 2 集群发送消息 3 集群消费 3 1 Procuder 3 2 Consumer 4 消费顺序 集群 对于kafka来说 一个单独的broker意味着kafka集群中只有一个节点 要想增加kafka集群中的
  • 计算机操作系统--UNIX操作系统

    UNIX操作系统 UNIX操作系统是一种多用户 多任务的分时操作系统 它由最内层的硬件提供基本服 务 内核提供全部应用程序所需的各种服务 UNIX文件系统 UNIX文件系统采用树形带交叉勾连的目录结构 根目录即为 非叶节点是目录 文件 叶节
  • DMA 突发模式

    这里的4个节拍 8个节拍 16个节拍的增量突发传输要如何解释 DMA传输需要用到总线矩阵 有个总线仲裁管理总线事务 由它来控制该谁谁用总线 普通的DMA传输可能传一个数据就必须跟总线仲裁提要求 总线仲裁才来安排传输 如果是增量突发传输 就是
  • 全局网络端口配置

    1 查询网络通路情况 curl cip cc 2 对网络进行配置 指定端口 export http proxy socks5 127 0 0 1 7890 export https proxy socks5 127 0 0 1 7890 查
  • openGL API glGenSamplers 详解

    暂时先放openGL官方文档的解释 后面我会加入中文翻译 Name glGenSamplers generate sampler object names C Specification void glGenSamplers GLsizei
  • 【开发工具】JAVA性能分析:3、超详细的JProfiler快照分析(官方中文版)

    Snapshots 快照分析 到目前为止 我们只查看了JProfiler GUI从配置文件JVM中运行的性能分析代理获取数据的实时会话 JProfiler还支持将所有分析数据写入文件的快照 在以下几种情况下 这可能是有利的 您可以自动记录分
  • Java中如何将Set转List呢?

    转自 Java中如何将Set转List呢 下文笔者讲述Java中Set转List的方法分享 如下所示 实现思路 方式1 借助ArrayList进行转换 方式2 借助List实现类的addAll 方法 例 Map
  • 栈之中缀表达式转后缀表达式

    题目描述 就是把我们平常写的运算表达式换成另外一种表达式 运算符前面两个数字执行相关操作 用图说明一下 比如3 2 gt 3 2 比如3 3 2 gt 3 3 2 再比如 3 3 2 2 3 gt 3 3 2 2 3 程序设计思路 特殊情况