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

**中缀表达式转后缀表达式的一般步骤如下:
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;
}

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

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何理解EDI报文,EDI报文标准以及版本号?

首先需要梳理EDI报文、EDI报文标准以及版本号这三个名词代表的不同含义。 EDI报文标准&#xff0c;即EDI文件在生成和解析时需要遵循的规则&#xff0c;通常情况下&#xff0c;在与交易伙伴实施EDI项目的过程中&#xff0c;交易双方需要按照同一套EDI报文标准处理文件&#xf…

Redis命令详解

文章目录 Key&#xff08;键&#xff09; DEL EXISTS EXPIRE EXPIREAT PEXPIRE PEXPIREAT PERSIST KEYS TTL PTTL RENAME RENAMENX TYPE SCAN HSCAN SSCAN ZSCAN DUMP String&#xff08;字符串&#xff09; SET GET INCR DECR MSET MGET APPEND SETNX STRLEN INCRBY DECRBY IN…

常见的几种计算机编码格式

前言&#xff1a; 计算机编码是指将字符、数字和符号等信息转换为计算机可识别的二进制数的过程&#xff0c;正因如此&#xff0c;计算机才能识别中英文等各类字符。计算机中有多种编码格式用于表示和存储文本、字符和数据&#xff0c;实际走到最后都是二进制&#xff0c;本质一…

【云原生-K8s】检查yaml文件安全配置kubesec部署及使用

基础介绍基础描述特点 部署在线下载百度网盘下载安装 使用官网样例yamlHTTP远程调用安全建议 总结 基础介绍 基础描述 Kubesec 是一个开源项目&#xff0c;旨在为 Kubernetes 提供安全特性。它提供了一组工具和插件&#xff0c;用于保护和管理在 Kubernetes 集群中的工作负载和…

Matplotlib plt.scatter()相关——(待完善)

1.python plt.scatter() 2.Python中的plt.scatter函数如何自定义颜色空间&#xff08;附详细代码&#xff09; 3.PYthon——plt.scatter各参数详解 4.plt.scatter()参数详解 5.plt.scatter各参数详解 6.plt.scatter( ) 函数的使用方法 7.matplot画图之plt.scatter()函数 8.Pyth…

计算机操作系统1

.11.操作系统的基本定义 2.操作系统的四大特征 2.1.操作系统的虚拟特征 3.操作系统的功能&#xff1a; 1.处理器管理 2.存储器管理 3.文件管理 4.设备管理 4.总结&#xff1a; 1.并发和共享互为存在&#xff0c;没有并发也就没有共享&#xff0c;反之也是。 2.并发和并行的…

Java多线程详解(上)——2023/11/23

Process&#xff08;进程&#xff09;与Thread&#xff08;线程&#xff09; 说起进程&#xff0c;就不得不说下程序。程序是指令和数据的有序集合&#xff0c;其本身没有任何运行的含义&#xff0c;是一个静态的概念。而进程则是执行程序的一次执行过程&#xff0c;它是一个动…

为什么C语言用int *a 来声明指针变量,而不是int a声明?

为什么C语言用int *a 来声明指针变量&#xff0c;而不是int &a声明&#xff1f; 在开始前我有一些资料&#xff0c;是我根据自己从业十年经验&#xff0c;熬夜搞了几个通宵&#xff0c;精心整理了一份「C语言从专业入门到高级教程工具包」&#xff0c;点个关注&#xff0c…

关系型数据库的数据隔离级别Read Committed与Repeatable Read

一、背景 数据库隔离级别会影响到我们的查询&#xff0c;本文试图以生产中的示例&#xff0c;给你一个直观的认识。 所谓&#xff0c;理论要结合实践&#xff0c;才能让我们理解得更加透彻。 另外&#xff0c;隔离级别的知识面很大&#xff0c;本文也不可能俱全&#xff0c;…

华为云RDS通用型(x86) vs 鲲鹏(ARM)架构的性能对比

概述 之前&#xff0c;我们对比了阿里云RDS的经济版&#xff08;ARM&#xff09;与x86版的性价比&#xff0c;这次我们来看看华为云的RDS MySQL的“通用型”(x86)与“鲲鹏通用增强型”(ARM)版本的情况如何。 这里依旧选择了用户较为常用的4c16g的规格进行测试&#xff0c;测试…

解读JetBrains 2023年开发者生态报告,MySQL仍是全球数据库顶流 | StoneDB数据库观察 #11

作者&#xff1a;宇亭 ​最近&#xff0c;全球知名的开发者工具公司 JetBrains 对外发布了《2023 年开发者生态系统报告》&#xff0c;报告的具体内容&#xff0c;前几天已经有中文互联网的媒体解读了&#xff0c;由于我们是做数据库的&#xff0c;所以自然而然想要特别关注一下…

模拟版图快速画图参考——《版图基础入门图解版》

模拟版图是IC行业门槛比较低的一个岗位&#xff0c;近年来有很多同学通过模拟版图来进入IC行业&#xff0c;本科生甚至是专科生都有这个机会。 学习模拟版图可能会有一些挑战&#xff0c;但通过系统性的学习、实践和逐步提升难度&#xff0c;今天为大家推荐一本经典的模拟版图…

c语言怎么“简单”表示9个变量互不相等?

c语言怎么“简单”表示9个变量互不相等? 在开始前我有一些资料&#xff0c;是我根据自己从业十年经验&#xff0c;熬夜搞了几个通宵&#xff0c;精心整理了一份「C语言从专业入门到高级教程工具包」&#xff0c;点个关注&#xff0c;全部无偿共享给大家&#xff01;&#xff0…

考研失利后,我是如何零基础转行测试开发 ,成功拿下独角兽公司offer?

想当年&#xff0c;从一个什么都不懂的非科班测试小白&#xff0c;考研失利后&#xff0c;转行到K12教育知名互联网公司做测试开发工程师&#xff0c;我用了大概半年的时间。 这个过程中我自己也摸索出了一条学习路线&#xff0c;在这里想给大家分享一下我的学习路线&#xff…

【Node.js】笔记梳理 8 - API和JWT

写在最前&#xff1a;跟着视频学习只是为了在新手期快速入门。想要学习全面、进阶的知识&#xff0c;需要格外注重实战和官方技术文档&#xff0c;文档建议作为手册使用 系列文章 【Node.js】笔记整理 1 - 基础知识【Node.js】笔记整理 2 - 常用模块【Node.js】笔记整理 3 - n…

uniapp踩坑之项目:使用过滤器将时间格式化为特定格式

利用filters过滤器对数据直接进行格式化&#xff0c;注意&#xff1a;与method、onLoad、data同层级 <template><div><!-- orderInfo.time的数据为&#xff1a;2023-12-12 12:10:23 --><p>{{ orderInfo.time | formatDate }}</p> <!-- 2023-1…

【算法】Boyer-Moore 算法

目录 1.概述1.1.Boyer-Moore 算法介绍1.2.坏字符规则表1.3.好后缀规则表1.4.总结 2.代码实现3.应用 更多数据结构与算法的相关知识可以查看数据结构与算法这一专栏。 有关字符串模式匹配的其它算法&#xff1a; 【算法】Brute-Force 算法 【算法】KMP 算法 【算法】Rabin-Karp …

Mac电脑vm虚拟机 VMware Fusion Pro中文 for mac

VMware Fusion Pro是一款功能强大的虚拟机软件&#xff0c;适用于需要在Mac电脑上运行其他操作系统的用户。它具有广泛的支持、快速稳定的特点以及多种高级功能&#xff0c;可以满足用户的各种需求和场景。 多操作系统支持&#xff1a;VMware Fusion Pro允许在Mac电脑上运行多…

合理的从度设置参数

环境&#xff1a;主库双1模式 一。单SQL线程 1.pos模式 1.1 position mode 模式&#xff08;最安全&#xff09; master_info_repository table relay_log_info_repository table recovery_relay_log off sync_master_info 1 sync_relay_log 1 sync_relay_log_in…

完善根文件系统

一. 简介 本文完善之前创建的根文件系统。 上一篇文章通过 设置 bootargs参数&#xff0c;使开发板通过 nfs服务从 ubuntu系统加载根文件系统。文章地址如下&#xff1a; 根文件系统初步测试-CSDN博客 二. 完善根文件系统 上一篇文章通过 设置 bootargs参数&#xff0c;使…