数据结构链表之栈——解决括号匹配问题和逆波兰表达式求值问题——6

括号匹配问题和逆波兰表达式求值问题

基于上一节已经使用python代码对栈进行了简单的实现,这一节我们在其基础上解决两个常见的问题

案例

  1. 括号匹配问题(点我直接到代码实现)
  2. 逆波兰表达式求值问题(点我直接到代码实现)

括号匹配问题

在给定的字符串中,编写程序实现确定该字符串类的括号是否匹配的问题
在这里插入图片描述
使用栈解决这个问题的思路:
在这里插入图片描述

括号匹配python代码实现

from Structure.linear.Stack import Stackdef is_matched_brackets(_str=None):stack = Stack()for s in _strs:# If the sub-str is '(', push it into the stackif s == '(':stack.push(s)# If it is ')', try to pop a '(' from the stackelif s == ')':pop_a_left = stack.pop()# If hadn't popped a '(', return falseif not pop_a_left:return Falseif stack.len == 0:return Truereturn False# _strs = "()(Shanghai)(Changan))("
# _strs = "())("
_strs = "(())()"
print(f"Is the brackets matched in {_strs} ? {is_matched_brackets(_strs)}")

然后这里导入的Stack是上一节栈的实现写的代码,也就使用到了pop和push的方法以及len属性,代码量也不算很多,我就直接复制过来了,方便查看,这里功能实现起来也是非常的简单,就不做过多赘述来解释了。

class Node:def __init__(self, item):self.item = itemself.next = Noneclass Stack:def __init__(self):self.head = Noneself.len = 0def is_empty(self):return not self.len# def length(self):#     return self.lendef push(self, item):"""Push an element into the stack"""node = Node(item)node.next = self.headself.head = nodeself.len += 1def pop(self):"""Pop a value from the stack top"""# if not self.head:#     raise IndexError("pop from empty list")cur = self.headif self.head:self.head = self.head.nextself.len -= 1return cur

逆波兰表达式

在定义逆波兰表达式求值问题之前,我们先来看一下中缀表达式是什么:

  • 定义:中缀表达式是一个通用的算术或逻辑公式表示方法,二元运算符总是会在两个操作数的中间

举个栗子:

  • 例如:1 + 3 * 2和2 - ( 1 + 3 ),运算符(+ - * /)都是在两个值的中间

这种表达式虽然对于我们人类来说观看和使用起来都是非常简单的,但是对于计算机并不太友好,这是因为这种表达式并不是有顺序的,在运算时还可能涉及到很多优先级顺序的判断

因此我们引入了中缀表达式转后缀表达式的概念,这里的后缀表达式就是我们所说的逆波兰表达式

  • 简介:逆波兰式(Reverse Polish notation,RPN,或逆波兰记法),也叫后缀表达式(将运算符写在操作数之后)

逆波兰表达式的定义描述看起来晦涩难懂,简单的说就是将运算符写在操作数之后的表达式,对定义描述感兴趣的同学可以自行百度一下,这里我们用几个例子直观的感受一下
在这里插入图片描述
通过结果看转换前的状态会比较好理解:

  1. a + b → ab+,先看操作符,一个操作符对应两个值,加号+对应a 和 b相加得到a+b
  2. a + (b - c) → abc-+,先看操作符,一个操作符对应两个值,减号-对应离他最近的bc,因此先计算b - c,再看加号+,也对于两个值,就是a 和 (b - c),因此为 a + (b - c)
  3. a + (b -c) * d → abc-d*+,先看操作符,秉承操作运算的先后顺序,减号-对应b - c,然后乘号*对应的是(b - c)*d,最后加号+对应的也是两个值a 和 (b - c)*d相加即可得到a + (b - c) * d
  4. a * (b - c) + d → abc-*d+,同样,以操作符为中心寻找数字,减号-对应b 和 c相减得到(b - c),乘号*对应a 和 (b - c)相乘得到a * (b - c),加号+对应a * (b - c)和 d,相加得到结果 a * (b - c) + d

代码实现思路:

  • 如果当前字符为变量或者为数字,则压栈,如果是运算符,则将栈顶两个元素弹出作相应运算,结果再入栈,最后当表达式扫描完后,栈里的就是结果。

实现流程图:
在这里插入图片描述

python代码实现
这里先要写一个实现栈的类方法:(也可以参照前期的栈实现文章)

class Node:def __init__(self, item):self.item = itemself.next = Noneclass Stack:def __init__(self):self.head = Noneself.len = 0def is_empty(self):return not self.len# def length(self):#     return self.lendef push(self, item):"""Push an element into the stack"""node = Node(item)node.next = self.headself.head = nodeself.len += 1def pop(self):"""Pop a value from the stack top"""# if not self.head:#     raise IndexError("pop from empty list")cur = self.headif self.head:self.head = self.head.nextself.len -= 1return cur
from Structure.linear.Stack import Stackdef reverse_polish_notation(_strs):nums = Stack()for s in _strs:if s not in ['+', '-', '*', '/']:nums.push(s)else:num1 = nums.pop().itemnum2 = nums.pop().item# This equals to num2 [+-*/] num1res = eval(str(num2)+s+str(num1))nums.push(res)return nums.pop().item# 2*(18-13)-12/4 = 2*5 - 3 = 7
_strs = '2', '18', '13', '-', '*', '12', '4', '/', '-'
result = reverse_polish_notation(_strs)
print(f"The computation of {_strs} is {2*(18-13)-12/4}")
print(f"The result is {result}")

运行结果:

The computation of ('2', '18', '13', '-', '*', '12', '4', '/', '-') is 7.0
The result is 7.0

实现过程比较简单,就不过多赘述了

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

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

相关文章

Java_基础阶段笔记总结汇总

一、Java简介 1、Java语言平台性介绍 2、JDK_JRE_JVM的组成和作用 JVM: Java虚拟机,是专门用来运行Java程序的,但是不能单独安装 JRE: Java运行环境,包含JVM(Java虚拟机,是专门用来运行Java程序的)和核心类库 JDK: Java开发工具包,包含JRE和…

数据结构链表之队列,Python3实现——7

数据结构链表之队列 队列概述 定义:队列是一种基于先进先出(FIFO)的数据结构,队列只能在一段进行插入和删除操作的结构,第一个进入队列的元素在读取时会第一个被读取 队列可以使用顺序表(Python中列表)实现,也可以用链表实现&am…

IDEA上Debug调试全流程

一、什么是Debug模式 是供程序员使用的程序调试工具,它可以用于查看程序的执行流程,也可以用于追踪程序执行过程来调试程序。使用IDEA的断点调试功能,查看程序的运行过程 Debug调试窗口介绍。 二、Debug模式操作流程【应用】 能够使用断点调…

数据结构链表之符号表,Python3实现——8

数据结构链表之符号表 符号表的介绍 之前章节介绍的顺序表和链表都是一个节点储存一个元素的表,但在日常生活中我们还有很多一次需要储存成对或多个值的情况,例如: 符号表最主要的目的将一对元素,用一个键和一个值将其联系起来&…

OpenCV_01 简介+无版权安装+模块分析

OpenCV是应用广泛的开源图像处理库,我们以其为基础,介绍相关的图像处理方法:包括基本的图像处理方法:几何变换,形态学变换,图像平滑,直方图操作,模板匹配,霍夫变换等&…

OpenCV_02 图像的基本操作:图像IO+绘制图形+像素点+属性+图像通道+色彩空间的改变

1 图像的IO操作 这里我们会给大家介绍如何读取图像,如何显示图像和如何保存图像。 1.1 读取图像 API cv.imread()参数: 要读取的图像 读取方式的标志 cv.IMREAD*COLOR:以彩色模式加载图像,任何图像的透明度都将被忽略。这是默…

数据结构之树:树的介绍——9

数据结构之树,介绍篇 树的基本定义 介绍:树(tree)是计算机中非常重要的数据结构,它的外形看起来像一颗倒挂着的的树,使用树这种结构可以描述生活中很多的事物,如族谱,单位的组织架…

OpenCV_03 图像的算数操作:图像的加法+图像的混合

1.图像的加法 你可以使用OpenCV的cv.add()函数把两幅图像相加,或者可以简单地通过numpy操作添加两个图像,如res img1 img2。两个图像应该具有相同的大小和类型,或者第二个图像可以是标量值。 注意:OpenCV加法和Numpy加法之间存…

数据结构之二叉树:二叉查找树的先序、中序、后序、层序遍历,Python代码实现——10(续)

数据结构之二叉查找树的代码实现 本节继续对上一节BST的功能实现 在实现之前,先对要实现的功能进行一下简单的介绍 BST的几种常见遍历方式 以一个简化的树为例,一棵树包含根(父)结点和其左子树及右子树: 遍历顺序的先后是指根(父)结点被遍…

OpenCV_04 几何变换:图像缩放+图像平移+图像旋转+仿射变换+透射变换+图像金字塔

1 图像缩放 缩放是对图像的大小进行调整,即使图像放大或缩小。 API cv2.resize(src,dsize,fx0,fy0,interpolationcv2.INTER_LINEAR)参数: src : 输入图像 dsize: 绝对尺寸,直接指定调整后图像的大小 fx,fy: 相对尺寸,将dsize设…

Direct2D教程(九)渲染位图

概述 这篇的标题更确切的说应该叫位图画刷,这样才好和前几篇对应起来。在Direct2D中,位图的渲染也是通过画刷来实现的。 Direct2D中并没有直接操作位图的接口,而是借助WIC(Windows Image Component)来完成的。今天我们…

OpenCV_05 形态学操作:连通性+腐蚀和膨胀+开闭运算+礼帽和黑帽

1 连通性 在图像中,最小的单位是像素,每个像素周围有8个邻接像素,常见的邻接关系有3种:4邻接、8邻接和D邻接。分别如下图所示: 4邻接:像素p(x,y)的4邻域是:(x1,y);(x-1,y)&#xff…

数据结构之二叉树:折纸问题——11

数据结构之二叉树:Python代码解决折纸问题 折纸问题 要求:请把一段纸条竖着放在桌子上,然后从纸条的下边向上方对折1次,压出折痕后展开。此时折痕是凹下去的,即折痕突起的方向指向纸条的背面。如果从纸条的下边向上方…

OpenCV_06 图像平滑:图像噪声+图像平滑+滤波

1 图像噪声 由于图像采集、处理、传输等过程不可避免的会受到噪声的污染,妨碍人们对图像理解及分析处理。常见的图像噪声有高斯噪声、椒盐噪声等。 1.1 椒盐噪声 椒盐噪声也称为脉冲噪声,是图像中经常见到的一种噪声,它是一种随机出现的白…

数据结构之堆:堆的介绍与python实现——12

堆的简单实现与代码实现 堆的定义 在定义堆(heap)之前,先回顾一下完全二叉树的定义: 完全二叉树:除了最后一层的结点有可能没有达到最大值外,其它层的结点值都达到最大值,此外最后一层的叶子…

OpenCV_07 直方图:灰度直方图+直方图均衡化

1 灰度直方图 1.1 原理 直方图是对数据进行统计的一种方法,并且将统计值组织到一系列实现定义好的 bin 当中。其中, bin 为直方图中经常用到的一个概念,可以译为 “直条” 或 “组距”,其数值是从数据中计算出的特征统计量&…

OpenCV_08 边缘检测:Sobel检测算子+Laplacian算子+Canny边缘检测

1 原理 边缘检测是图像处理和计算机视觉中的基本问题,边缘检测的目的是标识数字图像中亮度变化明显的点。图像属性中的显著变化通常反映了属性的重要事件和变化。边缘的表现形式如下图所示: 图像边缘检测大幅度地减少了数据量,并且剔除了可以…

数据结构之堆:堆的排序,Python代码实现——13

堆的排序,使用Python代码实现 上一节对堆进行了简单的实现,但是实现的堆只是部分有序(父结点大于子结点,子结点之间无序) 接下来我们实现对堆的所有元素进行升序排序 排序过程 实现步骤: 构造堆;得到堆顶元素,这个…

数据结构之优先队列:优先队列的介绍与基础操作实现,Python代码实现——14

优先队列(Priority queue)的介绍 优先队列是计算机中一种抽象的数据结构类,它有着一个类似和队列或者堆的结构,但是其中每个元素额外有一个优先级别在一个优先队列中,一个高优先顺序的元素会先执行与低优先顺序的元素。在它的执行过程中&…

初识--百年孤独

转载于:https://www.cnblogs.com/xmyun/articles/6306290.html