算法详解——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.hqwc.cn/news/527420.html

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

相关文章

CentOS网络故障排查秘笈:实战指南

前言 作为一名热爱折腾 Linux 的技术达人,我深知网络故障会让人抓狂!在这篇文章里,我和你分享了我的心得体会,从如何分析问题、识别瓶颈,到利用各种神器解决网络难题。不管你是新手小白还是老鸟大神,这里都…

计算机网络-第4章 网络层(2)

主要内容:网络层提供的两种服务:虚电路和数据报(前者不用)、ip协议、网际控制报文协议ICMP、路由选择协议(内部网关和外部网关)、IPv6,IP多播,虚拟专用网、网络地址转换NAT,多协议标…

Oracle Essbase 多维库导入文件数据步骤操作

第一步: 先确定导入数据的维度数量(清楚自己需要导入什么数据和范围) 第二步: 设置加载的规则 1.创建规则 2.编辑规则-》打开数据文件 通过数据文件来确定加载规则的加载格式 先查看数据文件格式: 将数据文件导入&…

jquery基础

1、jQuery的下载 官网地址:jQuery 版本: 1x:兼容IE678等低版本浏览器,官网不再更新 2x:不兼容IE678等低版本浏览器,官网不再更新 3x:不兼容IE678等低版本浏览器,是官方主要更新…

nmcli绑定bond双网卡(active-backup模式)

当前网卡mac地址IP都不一样 创建名为“jbl”的新连接,并将其模式设置为“active-backup” nmcli connection add type bond ifname jbl mode active-backup添加物理网卡到bond(JBL),两个物理网卡添加到新创建的bond连接中 nmcli connection add type bond-slave…

力扣--76. 最小覆盖子串

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。 注意: 对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。如…

js【详解】Promise

为什么需要使用 Promise ? 传统回调函数的代码层层嵌套,形成回调地狱,难以阅读和维护,为了解决回调地狱的问题,诞生了 Promise 什么是 Promise ? Promise 是一种异步编程的解决方案,本身是一个构…

[虚拟机保护逆向] [HGAME 2023 week4]vm

[虚拟机保护逆向] [HGAME 2023 week4]vm 虚拟机逆向的注意点:具体每个函数的功能,和其对应的硬件编码的*长度* 和 *含义*,都分析出来后就可以编写脚本将题目的opcode转化位vm实际执行的指令 :分析完成函数功能后就可以编写脚本输出…

【LangChain学习之旅】—(12) 代理(上):ReAct框架,推理与行动的协同

【LangChain学习之旅】—(12) 代理(上):ReAct框架,推理与行动的协同 代理的作用ReAct 框架通过代理实现 ReAct 框架总结时刻之前介绍的思维链(CoT)展示了 LLMs 执行推理轨迹的能力。在给出答案之前,大模型通过中间推理步骤(尤其是与少样本提示相结合)能够实现复杂的…

python编程从入门到实践答案二

python编程从入门到实践 第五章 if语句1.条件测试:2.更多的条件测试:3.外星人颜色#1:4. 外星人颜色#2:5. 外星人颜色#3:6. 人生的不同阶段:7. 喜欢的水果:8. 以特殊方式跟管理员打招呼&#xff…

2024年【电工(初级)】考试内容及电工(初级)考试报名

题库来源:安全生产模拟考试一点通公众号小程序 电工(初级)考试内容根据新电工(初级)考试大纲要求,安全生产模拟考试一点通将电工(初级)模拟考试试题进行汇编,组成一套电…

MySQL中常用的操作语句已汇总

目录 一、库语句 1.查询现有数据库 2.创建数据库 3.选中数据库 ​编辑 4.删除数据库 二、初阶表操作 1.查看数据库现有表 2.查看表结构 3.创建表 4.删除表 5.全列查询 6.删除表2 7.修改操作 三、插入操作 1.全列插入 2.指定列插入 3.一次插入多组数据 4.插入…