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

欢迎来看博主的算法讲解
博主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.mzph.cn/news/734736.shtml

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

相关文章

el-table 插入输入框并进行校验

<template><div><el-form :model"list" ref"ruleForm"><el-table :data"list.tableData" style"width: 100%"><el-table-column prop"time" label"日期" width"180"><…

一周学会Django5 Python Web开发-Django5内置模板引擎-模板标签

锋哥原创的Python Web开发 Django5视频教程&#xff1a; 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计33条视频&#xff0c;包括&#xff1a;2024版 Django5 Python we…

HCIA-HarmonyOS设备开发认证V2.0-习题2

目录 习题一习题二坚持就有收获 习题一 # 判断题## 1.PWM占空比指的是低电平时间占周期时间的百分比。(错误)正确(True)错误(False)解题&#xff1a; - PWM占空比指的是高电平时间占周期时间的百分比## 2.UART是通用异步收发传输器&#xff0c;是通用串行数据总线&#xff0c;…

ROS2学习(七) Foxy版本ros2替换中间件。

在ros2使用的过程中&#xff0c;一开始选用的foxy版本&#xff0c;后来发现&#xff0c;foxy版本的ros2有很多问题。一个是foxy版本已经停止维护了。另一个问题是这个版本有很多bug, 后续的版本在功能实现上做了很大的改动&#xff0c;甚至说进行了重写。修复的一些问题&#x…

动态规划

动态规划 动态规划&#xff08;DP&#xff09;是一种对问题的状态空间进行分阶段、有顺序、不重复、决策性遍历的算法。关键与前提 重叠子问题&#xff1a;与递归、分治等一样&#xff0c;要具有同类子问题&#xff0c;用若干维状态表示。最优子结构&#xff1a;状态对应着一个…

四、软考-系统架构设计师笔记-信息系统基础知识

1、信息系统概述 信息系统的定义 信息系统是由计算机硬件、网络和通信设备、计算机软件、信息资源、信息用户和规章制度组成的以处理信息流为目的的人机一体化系统。 信息系统任务是对原始数据进行收集、加工、存储&#xff0c;并处理产生各种所需信息&#xff0c;以不同的方式…

修改Android打包apk的名字和目录

app打包生成apk后通常需要进行备份&#xff0c;但是要区分好哪个apk是什么版本的、什么时候打包的&#xff0c;以方便以后区分使用。 最开始的想法是把版本号、创建时间这些加在apk文件名上即可&#xff0c;但是公司要求apk使用一个固定的名称&#xff0c;那我怎么保存版本号信…

Ubuntu平铺左、右、上、下、1/2、1/4窗口(脚本)

前言 之前因为一直在用Ubuntu 18或者Ubuntu 20然后发现装了GNOME插件后&#xff0c;电脑在使用过程中&#xff0c;会时不时的卡死&#xff08;鼠标没问题&#xff0c;键盘输入会有10-20秒的延迟&#xff09;频率基本是一小时一次&#xff0c;因为这种卡顿会很容易打断思路&…

Jenkins 部署 RuoYi

目录 1、项目介绍 2、部署若依 clone 源代码 导入数据库到 node-16 修改 RuoYi 配置文件 推送 RuoYi 项目至 Gitlab 3、配置 Jenkins 配置本地 Maven Jenkins 配置 Maven 新建 Maven 项目 编写构建后的脚本 Jenkins 构建后执行脚本 4、Jenkins 传递参数 设置项目部…

React 19 Cheat Sheet

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

maven 进行jdbc 查询

a. 在pom.xml 增加 依赖 mysql-connector-java依赖b. 编写 实体类, 按照 数据库表 生成对应的 类数据库类型 java 类型int intvarchar Stringdatetime java.util.Date注意事项: 属性名 采用 驼峰式命名法实体类 要求采用 封装的写…

MySQL之主从同步(openEuler版)

实验目的&#xff1a; 基于binlog和gtid两种方法实现主从同步 实验过程&#xff1a; 一、使用binlog方法实现MySQL的主从同步 主库配置 配置文件&#xff1a; [rootopeneuler ~]# vim /etc/my.cnf//进入mysql配置文件配置server_id [rootopeneuler ~]# tail -1 /etc/my.cn…

股票价格预测项目

项目介绍 背景 股票价格预测一直是金融领域的热点问题。准确的预测可以帮助投资者作出更明智的决策。本项目旨在使用机器学习技术&#xff0c;特别是长短期记忆网络&#xff08;LSTM&#xff09;&#xff0c;来预测股票价格。 目标 开发一个基于LSTM的股票价格预测模型。使…

使用 Logstash 丰富你的 Elasticsearch 文档

作者&#xff1a;来自 Elastic David Pilato 我们在上一篇文章中看到&#xff0c;我们可以使用摄取管道中的 Elasticsearch Enrich Processor 在 Elasticsearch 中进行数据丰富。 但有时&#xff0c;你需要执行更复杂的任务&#xff0c;或者你的数据源不是 Elasticsearch&#…

python的scripts文件夹作用

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

集简云新增通义千问qwen 72b chat、qwen1.5 等多种大语言模型,提升多语言支持能力

通义千问再开源&#xff01;继发布多模态模型后&#xff0c;通义千问 1.5 版本也在春节前上线。 此次大模型包括六个型号&#xff1a;0.5B、1.8B、4B、7B、14B 和 72B&#xff0c;性能评测基础能力在在语言理解、代码生成、推理能力等多项基准测试中均展现出优异的性能&#x…

大话设计模式——5.代理模式(Proxy Pattern)

1.定义 为其他具体对象提供一种代理用以控制对这个对象的访问&#xff0c;属于结构型模式。 UML图&#xff1a; 2.示例 生活中有许多的代理&#xff0c;如房产中介&#xff0c;房主出售的房子挂在中介处&#xff0c;中介帮忙寻找需要的客户&#xff0c;客户不需要直接接触房…

linux tar分卷压缩与windows合并解压

linux tar分卷压缩 tar -czf - Shadowsocks | split -b 1000k -d - shadowsocks.tar.gz tar -czf - 文件夹名 | split -b 1000k -d - 输出文件 如有如下几个tar分卷&#xff1a;logs.tar.gza1、logs.tar.gza2、logs.tar.gza3&#xff0c;在Windows下如何进行合并呢&#xff…

【备战蓝桥杯系列】单源最短路径Dijkstra算法模板

Dijkstra算法模板 蓝桥杯中也是会考到图论最短路的&#xff0c;一旦考到&#xff0c;基本是不会太难的&#xff0c;只要知道板子就基本能拿分了。 两个板子如下 朴素Dijkstra算法 适应情况&#xff1a;稠密图&#xff0c;正权边 时间复杂度 O(n^2 m) int dijkst(){memse…

银河麒麟服务器ky10 server wvp镜像制作

在线安装docker yum install docker -y cat >/etc/docker/daemon.json<<EOF{"registry-mirrors": ["https://registry.docker-cn.com","https://dockerhub.azk8s.cn","https://hub-mirror.c.163.com"]} EOF systemctl start …