算法详解——leetcode150(逆波兰表达式)

news2024/11/19 4:44:01

欢迎来看博主的算法讲解
博主ID:代码小豪

文章目录

    • 逆波兰表达式
    • 逆波兰表达式的作用
    • 代码
    • 将中缀表达式转换成后缀表达式
    • 文末代码

逆波兰表达式

先来看看leetcode当中的原题
在这里插入图片描述
大多数人初见逆波兰表达式的时候大都一脸懵逼,因为与平时常见的表达式不同,很难将常见的表达式与逆波兰表达式联系在一次。

比如:
常见表达式(中缀表达式):((2 + 1) * 3) = 9。
其逆波兰表达式为(后缀表达式):2 1+ 3 *

再解决这个问题之前,首先我们先来了解一下为什么要用逆波兰表达式,而不是中缀表达式呢?

逆波兰表达式的作用

对于人来说,中缀表达式显然是通俗易懂的,但是如果让计算机来处理输入的中缀表达式呢?大家可以想想该如何实现。

显而易见,计算机处理输入的中缀表达式是较为麻烦的。为了解决让计算机便于进行四则运算,逆波兰表达式被发明出来了。

逆波兰表达式的计算方式如下:
将逆波兰表达式从头开始遍历,如果遇到数字,就将数字压入栈中,如果遇到符号,就将栈顶的两个数字弹出,并将计算结果压入栈中。

以:2 1+ 3 *
为例
将2,1压入栈中,遇到+,将1,2弹出,1+2=3,将计算结果的3压入栈中。接着再将3压入栈中,遇到*将3,3弹出,3*3=9,最终结果为9.
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
通过了解后缀表达式的计算方法后,可以发现后缀表达式可以通过栈操作来计算出来,这也是计算机中常见的存储结构之一。这就是逆波兰表达式的意义。

既然已经知道了逆波兰表达式的计算方法,那么完成这道题就不难了。

代码

//以下是栈的操作函数
typedef int datatype;
typedef struct stack
{
	datatype* data;
	int capacity;
	int top;
}stack;

void StackInit(stack* ps);//将栈进行初始化
void StackDestory(stack* ps);//释放栈空间

void StackPush(stack* ps, datatype n);//压栈操作
void StackPop(stack* ps);//出栈操作

datatype StackTopData(stack* ps);//获取栈顶
bool StackEmpty(stack* ps);//判断栈是否为空

//逆波兰表达式的函数
int evalRPN(char** tokens, int tokensSize) {
	stack* rpn = malloc(sizeof(stack));
	StackInit(rpn);//初始化栈空间
	int ret = 0;
	while (tokensSize--)//遍历整个后缀表达式
	{
		if (**tokens == '+' ||//判断符号
			**tokens == '-' ||
			**tokens == '*' ||
			**tokens == '/')
		{
			if (strlen(*tokens) == 1)//由于测试案例中有“-1”这种特殊字符串,因此设计的判断条件。
			{
				int num1 = StackTopData(rpn);
				StackPop(rpn);
				int num2 = StackTopData(rpn);
				StackPop(rpn);

				switch (**tokens)
				{
				case '+':StackPush(rpn, num2 + num1);
					break;
				case'-':StackPush(rpn, num2 - num1);
					break;
				case'*':StackPush(rpn, num2 * num1);
					break;
				case'/':StackPush(rpn, num2 / num1);
					break;
				}
			}
			else {
				int num = 0;
				num = atoi(*tokens);
				StackPush(rpn, num);
			}
		}
		else
		{
			int num = 0;
			num = atoi(*tokens);//将字符转换成整型数据(库函数)
			StackPush(rpn, num);
		}
		tokens++;
	}
	ret = StackTopData(rpn);//将计算结果弹出栈
	StackDestory(rpn);
	return ret;//返回计算结果
}

(为了节省篇幅,将栈的相关操作的函数定义进行省略,如果想要完整版代码,可以再文章末尾查看)

将中缀表达式转换成后缀表达式

力扣当中的原题直接将后缀表达式作为输入,因此在完成这道题时并不需要考虑将中缀表达式转换成后缀表达式。

后缀表达式是为了让计算机能用栈来处理四则运算,所以后缀表达式的主要作用是按照顺序来,展示中缀表达式的优先级。

比如:2 1+ 3 *
其中缀表达式为(2+1)*3
()的优先级高于*,因此先将优先级高的数字进行计算,即(2+1),。接着计算*3,因此总体的计算方式为2+1,接着*3,为了满足前边所讲的栈操作,因此应该写为2 1 +(先算2+1)。然后3*,总体上为2 1 + 3 *.

将中缀表达式转换成后缀表达式的过程也可以用栈来实现,原理如下:
建立一个栈,用于压入符号。遇到数字直接输出就行。
(1)判断压入栈中的符号的优先级是否高于栈顶,如果不高于栈顶,则将栈内的所有符号弹出,再把符号压入栈中
(2)将()括号内的符号弹出栈
以9+(3-1)*3+10/2为例。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

文末代码

typedef int datatype;
typedef struct stack
{
	datatype* data;
	int capacity;
	int top;
}stack;

void StackInit(stack* ps);
void StackDestory(stack* ps);

void StackPush(stack* ps, datatype n);
void StackPop(stack* ps);

datatype StackTopData(stack* ps);
bool StackEmpty(stack* ps);

void StackInit(stack* ps)
{
	if (ps == NULL)
	{
		ps = malloc(sizeof(stack));
		return ;
	}
	ps->data = NULL;
	ps->capacity = 0;
	ps->top = 0;
}

void StackPush(stack* ps, datatype e)
{
	assert(ps);

	if (ps->capacity == ps->top)
	{
		int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		ps->capacity = newcapacity;
		stack* tmp = realloc(ps->data, ps->capacity * sizeof(datatype));
		assert(tmp);
		ps->data = tmp;
	}

	ps->data[ps->top] = e;
	ps->top++;
}

void StackPop(stack* ps)
{
	if (StackEmpty(ps))
	{
		perror("Stack is empty\n");
		return;
	}

	ps->top--;
}

bool StackEmpty(stack* ps)
{
	return ps->top == 0;
}

datatype StackTopData(stack* ps)
{
	if (StackEmpty(ps))
	{
		perror("Stack is empty\n");
		exit(1);
	}
	return ps->data[ps->top - 1];
}

void StackDestory(stack* ps)
{
	assert(ps);
	free(ps->data);
	ps->data = NULL;
	ps->top = 0;
	ps->capacity = 0;
}

int evalRPN(char** tokens, int tokensSize) {
	stack* rpn=malloc(sizeof(stack));
	StackInit(rpn);
	int ret = 0;
	while (tokensSize--)
	{
		if (**tokens == '+' ||
			**tokens == '-' ||
			**tokens == '*' ||
			**tokens == '/')
		{
			if (strlen(*tokens) == 1)
			{
				int num1 = StackTopData(rpn);
				StackPop(rpn);
				int num2 = StackTopData(rpn);
				StackPop(rpn);

				switch (**tokens)
				{
				case '+':StackPush(rpn, num2 + num1);
					break;
				case'-':StackPush(rpn, num2 - num1);
					break;
				case'*':StackPush(rpn, num2 * num1);
					break;
				case'/':StackPush(rpn, num2 / num1);
					break;
				}
			}
			else {
				int num = 0;
				num = atoi(*tokens);
				StackPush(rpn, num);
			}
		}
		else
		{
			int num = 0;
			num = atoi(*tokens);
			StackPush(rpn, num);
		}
		tokens++;
	}
	ret = StackTopData(rpn);
	StackDestory(rpn);
	return ret;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

华为配置DHCP Snooping防止DHCP Server仿冒者攻击示例

配置DHCP Snooping防止DHCP Server仿冒者攻击示例 组网图形 图1 配置DHCP Snooping防止DHCP Server仿冒者攻击组网图 DHCP Snooping简介配置注意事项组网需求配置思路操作步骤配置文件 DHCP Snooping简介 在一次DHCP客户端动态获取IP地址的过程中,DHCP Snoopi…

基于Vue的娱讯移动端APP前端设计与实现

目 录 摘 要 Abstract 引 言 1绪论 1.1课题背景及目的 1.1.1移动端APP发展简介 3 1.1.2移动端APP的优势 3 1.2前端开发相关技术 1.2.1前端开发工具介绍 3 1.2.2 前端开发相关技术介绍 4 1.3本章小结 2系统分析 2.1功能需求分析 2.2系统工作流程 2.3本章小结 3系统设…

Linux 之七:Linux 防火墙 和进程管理

防火墙 查看防火墙 查看 Centos7 的防火墙的状态 sudo systemctl status firewalld。 查看后,看到active(running)就意味着防火墙打开了。 关闭防火墙,命令为: sudo systemctl stop firewalld。 关闭后查看是否关闭成功,如果…

python的scripts文件夹作用

Windows系统: Scripts文件夹通常位于Python的安装目录下,如C:\Python\Scripts。该文件夹内包含了各种有用的工具,例如pip、virtualenv等,这些工具有助于管理和配置Python环境和依赖包。 Linux系统: 在Linux系统中&…

【大厂AI课学习笔记NO.69】使用开源管理仓库

了解了开源框架,开源项目,今天来学习开源管理仓库。 我们先说Git,开源的版本管理分布式系统。 GitHub,则是世界上最大的代码托管平台,面向开源和私有项目托管。 有的人总是分不清这两个,其实一个是版本管…

凌鲨微应用架构

微应用是静态网页加上凌鲨提供的扩展能力而形成的一种应用,主要特点是开发便捷,安全。 微应用架构 组件说明 名称 说明 微应用 webview窗口,显示web服务器上的页面 接口过滤器 根据权限配置,屏蔽非授权接口访问 接口提供者 tauri注入…

循序渐进丨MogDB 数据库特性之动态数据脱敏机制

数据脱敏是行之有效的数据库隐私保护方案之一,可以在一定程度上限制非授权用户对隐私数据的窥探。动态数据脱敏机制是一种通过定制化脱敏策略来实现对隐私数据保护的技术,可以在保留原始数据的前提下有效地解决非授权用户对敏感信息访问的问题。当管理员…

C#,蛇梯问题(Snake and Ladder Problem)的算法与源代码

1 蛇梯问题 Snake and Ladder Problem 给定一个蛇梯板,找出从源单元格或第一个单元格到达目标单元格或最后一个单元格所需的最小掷骰次数。基本上,玩家可以完全控制掷骰子的结果,并希望找出到达最后一个单元格所需的最小掷骰次数。 如果玩…

基于鳑鲏鱼优化算法(Bitterling Fish Optimization,BFO)的无人机三维路径规划

一、无人机路径规划模型介绍 无人机三维路径规划是指在三维空间中为无人机规划一条合理的飞行路径,使其能够安全、高效地完成任务。路径规划是无人机自主飞行的关键技术之一,它可以通过算法和模型来确定无人机的航迹,以避开障碍物、优化飞行…

gradle下载太慢者超时!国内镜像可以直接下载

# 解决Gradle下载过慢问题的有效方式:使用国内镜像站点 在开发过程中,我们经常会遇到Gradle下载速度缓慢或超时的问题。作为一个强大而流行的构建工具,Gradle是许多项目中必不可少的一部分。然而,由于官方下载地址可能受网络限制…

Windows10/11配置WSL(Ubuntu)环境

文章目录 WSL介绍WSL部署扩展:辅助工具Windosw Terminal安装下载 WSL介绍 传统方式获取Linux操作系统,是安装完整的虚拟机及镜像环境,例如虚拟机VMware 而使用WSL,可以以非常轻量化的方式,得到Linux系统环境 它无需单独虚拟一套硬…

React 19 Cheat Sheet

React 19让构建网站和应用程序变得更容易,更好。有了很酷的新东西,比如React编译器、Actions API和更好的Hooks,编写代码变得更快,管理应用程序的数据变得更简单 React 19让构建网站和应用程序变得更容易,更好。有了很…

vue组件之间通信方式汇总

方式1&#xff1a;props和$emit props和$emit仅仅限制在父子组件中使用 1.props&#xff1a;父组件向子组件传递数据 1.1 代码展示 <template><div><!-- 这是父组件 --><div>父组件中的基本数据类型age的值是:{{this.age}}</div><div>…

C++的一些基础语法

前言&#xff1a; 本篇将结束c的一些基础的语法&#xff0c;方便在以后的博客中出现&#xff0c;后续的一些语法将在涉及到其它的内容需要用到的时候具体展开介绍&#xff1b;其次&#xff0c;我们需要知道c是建立在c的基础上的&#xff0c;所以c的大部分语法都能用在c上。 1.…

【Docker】容器的概念

容器技术&#xff1a;容器技术是基于虚拟化技术的&#xff0c;它使应用程序从一个计算机环境快速可靠地转移到另一个计算机环境中&#xff0c;可以说是一个新型地虚拟化技术。 一、docker容器 Docker:是一个开源地容器引擎Docker 是一种轻量级的容器化技术&#xff0c;其主要原…

雷赛控制卡获取轴当前位置的值不正确问题处理

现像 从雷赛控制卡中获取当前轴位置值时发现轴在向零点的右边走时显示的值是负数。正常来就一般是要反馈正数的。一般轴零点右边是正方向&#xff0c;限位是正限位&#xff0c;反馈的位置也应该是正数。 如果雷赛软件中的【单轴参数】中的基本设置中的【脉冲模式】设置的是对的…

【神经网络与深度学习】LSTM(Long Short-Term Memory)神经网络模型

概述 LSTM&#xff08;Long Short-Term Memory&#xff09;是一种特殊的循环神经网络&#xff08;RNN&#xff09;结构&#xff0c;通常被用于处理和学习时间序列数据。因此&#xff0c;LSTM属于深度学习领域中的一种神经网络模型。 在深度学习中&#xff0c;LSTM被广泛应用于…

【轮式平衡机器人】——TMS320F28069片内外设之eCAP

引入 TMS320F28069的eCAP&#xff08;增强型捕获模块&#xff09;是一个强大的外设&#xff0c;用于精确测量和捕获输入信号的事件和时间戳。 在电机控制、传感器数据采集和信号处理等应用中&#xff0c;eCAP模块可以用于测量霍尔传感器、编码器或其他数字输入信号的周期、频…

MySQL 的基础操作

数据库的基础操作 1. 库操作2. 表的操作3. 数据类型 数据库是现代应用程序中至关重要的组成部分&#xff0c;通过数据库管理系统&#xff08;DBMS&#xff09;存储和管理数据。 1. 库操作 创建数据库 创建数据库是开始使用数据库的第一步。下面是一些常见的创建数据库的示例&a…

为什么在镀膜时要测薄膜折射率?

在芯片制造中&#xff0c;镀膜工序&#xff08;PVD,CVD&#xff09;是必不可少的关键环节&#xff0c;薄膜的质量直接影响了芯片的性能。对这些薄膜的精细控制又离不开对其折射率的深入理解和精确测量。今天将对芯片制造中薄膜折射率的概念、测量方法&#xff0c;以及它在整个制…