数据结构编程实践20讲(Python版)—03栈

本文目录

    • 03 栈 Stack
      • S1 说明
      • S2 示例
        • 基于列表的实现
        • 基于链表的实现
      • S3 问题:复杂嵌套结构的括号匹配问题
        • 求解思路
        • Python3程序
      • S4 问题:基于栈的阶乘计算VS递归实现
        • 求解思路
        • Python3程序
      • S5 问题:逆波兰表示法(后缀表达式)求值
        • 求解思路
        • Python3程序

往期链接

01 数组02 链表

03 栈 Stack

S1 说明

栈是一种线性数据结构,具有后进先出(LIFO, Last In First Out)的特点。栈的主要操作包括插入(压栈)和删除(弹栈),这些操作只能在栈的顶端进行。

基本操作

  • 压栈(Push):将一个元素添加到栈顶。
  • 弹栈(Pop):从栈顶移除并返回一个元素。
  • 查看栈顶元素(Peek/Top):返回栈顶元素,但不删除它。
  • 检查栈是否为空(IsEmpty):判断栈中是否还有元素。
  • 获取栈的大小(Size):返回栈中元素的数量。

性质

  • 后进先出(LIFO):最后压入栈的元素最先弹出。
  • 只能在栈顶进行操作,无法直接访问栈中间或底部的元素。

S2 示例

基于列表的实现
class Stack:def __init__(self):self.items = []  # 使用列表存储栈元素def push(self, item):"""压栈操作"""self.items.append(item)def pop(self):"""弹栈操作"""if not self.is_empty():return self.items.pop()raise IndexError("弹栈失败,栈为空")def peek(self):"""查看栈顶元素"""if not self.is_empty():return self.items[-1]raise IndexError("查看栈顶元素失败,栈为空")def is_empty(self):"""检查栈是否为空"""return len(self.items) == 0def size(self):"""获取栈的大小"""return len(self.items)# 使用示例
if __name__ == "__main__":stack = Stack()stack.push(1)stack.push(2)stack.push(3)print("栈顶元素:", stack.peek())  # 输出 3print("弹出元素:", stack.pop())    # 输出 3print("当前栈大小:", stack.size())  # 输出 2

输出

栈顶元素: 3
弹出元素: 3
当前栈大小: 2
基于链表的实现
class Node:"""链表节点类"""def __init__(self, value):self.value = value  # 节点存储的值self.next = None    # 指向下一个节点的指针class LinkedListStack:"""基于链表的栈类"""def __init__(self):self.top = None  # 栈顶指针def push(self, value):"""压栈操作"""new_node = Node(value)  # 创建新节点new_node.next = self.top  # 新节点指向当前栈顶self.top = new_node  # 更新栈顶为新节点def pop(self):"""弹栈操作"""if self.is_empty():raise IndexError("弹栈失败,栈为空")popped_value = self.top.value  # 保存栈顶值self.top = self.top.next  # 更新栈顶为下一个节点return popped_value  # 返回弹出的值def peek(self):"""查看栈顶元素"""if self.is_empty():raise IndexError("查看栈顶元素失败,栈为空")return self.top.value  # 返回栈顶值def is_empty(self):"""检查栈是否为空"""return self.top is None  # 栈顶指针为空则栈为空def size(self):"""获取栈的大小"""count = 0current = self.topwhile current:count += 1current = current.nextreturn count# 使用示例
if __name__ == "__main__":stack = LinkedListStack()stack.push(10)stack.push(20)stack.push(30)print("栈顶元素:", stack.peek())  # 输出 30print("弹出元素:", stack.pop())    # 输出 30print("当前栈大小:", stack.size())  # 输出 2print("栈是否为空:", stack.is_empty())  # 输出 False# 弹出剩余元素print("弹出元素:", stack.pop())    # 输出 20print("弹出元素:", stack.pop())    # 输出 10print("栈是否为空:", stack.is_empty())  # 输出 True

输出

栈顶元素: 30
弹出元素: 30
当前栈大小: 2
栈是否为空: False
弹出元素: 20
弹出元素: 10
栈是否为空: True

S3 问题:复杂嵌套结构的括号匹配问题

‌括号匹配问题‌是一个在算法和数据结构中常见的问题,主要目标是通过检查输入的括号序列是否平衡和闭合,以确定它们是否匹配。这个问题涉及到各种类型的括号,如圆括号、花括号和大括号。

括号匹配问题的核心在于检查输入的括号序列中的左括号和右括号是否能够正确配对,并且配对的顺序是否正确。例如,在算术表达式中,需要确保每一个左括号(如“(”或“[”)都有一个相应的右括号(如“)”或“]”)来闭合它,并且这些括号必须按照正确的顺序闭合。如果输入的括号序列无法满足这些条件,则称该序列不匹配。

要判断的括号字符串:

expressions = ["({[()]}{[()]})",  # 匹配"{([()][()])}{[()]()}",  # 匹配"({[()]}{[(])})",  # 不匹配"({[()]}([]{}))"  # 不匹配
]
求解思路
  • 使用一个栈(用Python的列表实现)来跟踪开放的括号。
  • 定义开放括号和闭合括号的集合,以及一个配对字典。
  • 遍历输入字符串中的每个字符:
    • 如果是开放括号,将其推入栈中。
    • 如果是闭合括号,检查栈是否为空(如果为空,则不平衡),然后检查栈顶元素是否与当前闭合括号匹配。如果匹配,则弹出栈顶元素;如果不匹配,则表达式不平衡。
  • 最后,如果栈为空,则表达式平衡;否则不平衡。
Python3程序
def is_balanced(expression):# 初始化一个空栈,用于存储开放括号stack = []# 定义开放括号的集合opening = "({["# 定义闭合括号的集合closing = ")}]"# 定义括号对应关系的字典pairs = {")": "(", "}": "{", "]": "["}# 遍历表达式中的每个字符for char in expression:# 如果是开放括号,将其压入栈中if char in opening:stack.append(char)# 如果是闭合括号elif char in closing:# 如果栈为空,说明闭合括号没有对应的开放括号,返回Falseif not stack:return False# 如果栈顶的开放括号与当前闭合括号匹配if stack[-1] == pairs[char]:# 弹出栈顶元素stack.pop()else:# 如果不匹配,返回Falsereturn False# 遍历结束后,如果栈为空,说明所有括号都匹配,返回True;否则返回Falsereturn len(stack) == 0# 测试样例
expressions = ["({[()]}{[()]})",  # 匹配"{([()][()])}{[()]()}",  # 匹配"({[()]}{[(])})",  # 不匹配"({[()]}([]{}))"  # 不匹配
]# 遍历所有测试样例
for expr in expressions:# 调用is_balanced函数检查是否平衡,并打印结果print(f"'{expr}'是{'匹配的' if is_balanced(expr) else '不匹配的'}")

输出

'({[()]}{[()]})'是匹配的
'{([()][()])}{[()]()}'是匹配的
'({[()]}{[(])})'是不匹配的
'({[()]}([]{}))'是匹配的

S4 问题:基于栈的阶乘计算VS递归实现

求解思路

使用栈实现的非递归版本。它的工作原理如下:

  • 初始化一个栈和结果变量。
  • 将初始值n压入栈中。
  • 当栈不为空时,循环处理:
    • 弹出栈顶元素。
    • 如果是0或1,直接继续(因为0!和1!都等于1)。
    • 否则,将当前值乘到结果中,并将下一个要处理的值(当前值-1)压入栈中。
  • 循环结束后,返回最终结果。
Python3程序
# 递归版本的阶乘计算
def factorial_recursive(n):if n == 0 or n == 1:return 1else:return n * factorial_recursive(n - 1)# 使用栈的非递归版本的阶乘计算
def factorial_iterative(n):# 初始化一个栈来模拟递归调用stack = []result = 1# 将初始值压入栈中stack.append(n)# 当栈不为空时,继续处理while stack:# 从栈顶取出当前要处理的值current = stack.pop()if current == 0 or current == 1:# 0!和1!的值都是1,不需要further处理continueelse:# 将当前值乘到结果中result *= current# 将下一个要处理的值压入栈中stack.append(current - 1)return result# 测试两个版本的阶乘函数
test_numbers = [100]print("递归版本结果:")
for num in test_numbers:print(f"{num}! = {factorial_recursive(num)}")print("\n非递归版本结果:")
for num in test_numbers:print(f"{num}! = {factorial_iterative(num)}")

输出

递归版本结果:
100! = 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000非递归版本结果:
100! = 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

S5 问题:逆波兰表示法(后缀表达式)求值

逆波兰表示法(Reverse Polish Notation, RPN)是一种数学表达式的表示方式,其中运算符跟在操作数后面。这种表示法的优点是可以不使用括号来明确运算的优先级,因为操作数的顺序和运算符的顺序自然决定了计算的顺序。逆波兰表示法的特点

  • 无括号:在逆波兰表示法中,运算符总是位于操作数之后,因此不需要括号来改变运算顺序。
  • 后进先出(LIFO)原则:通常使用栈来计算逆波兰表达式。操作数被压入栈中,运算符则从栈中弹出操作数进行计算。

为什么要将看似简单的中缀表达式转换为复杂的逆波兰式?原因就在于对计算机而言 中序表达式(中缀表达式,我们常用的数学表达式的表示方式,带有括号,并且有运算优先级) 是非常复杂的结构。相对的,逆波兰式在计算机看来却是比较简单易懂的结构。因为计算机普遍采用的内存结构是栈式结构,它执行先进后出的顺序。

中缀表达式:3 + (51 * 2) - 80 / (4 - 2)
后缀表达式:转换后的形式为 3 51 2 * + 80 4 2 - / -

后缀表达式的计算
从左到右开始读取后缀表达式:
(1) 读到 3,入栈。此时栈:[3]
(2) 读到 51,入栈。此时栈:[3, 51]
(3) 读到 2,入栈。此时栈:[3, 51, 2]
(4) 读到 ∗ * ,取出栈顶两个数字进行乘法运算:51 * 2 = 102,结果入栈。此时栈:[3, 102]
(5) 读到 + + +,取出栈顶两个数字进行加法运算:3 + 102 = 105,结果入栈。此时栈:[105]
(6) 读到 80,入栈。此时栈:[105, 80]
(7) 读到 4,入栈。此时栈:[105, 80, 4]
(8) 读到 2,入栈。此时栈:[105, 80, 4, 2]
(9) 读到 − - ,取出栈顶两个数字进行减法运算:4 - 2 = 2,结果入栈。此时栈:[105, 80, 2]
(10) 读到 / / /,取出栈顶两个数字进行除法运算:80 / 2 = 40,结果入栈。此时栈:[105, 40]
(11) 读到 − - ,取出栈顶两个数字进行减法运算:105 - 40 = 65,结果入栈。此时栈:[65]

计算结束,栈中只剩下一个数字,这就是最终结果。因此,表达式 3 51 2 * + 80 4 2 - / - 的计算结果是65

现在计算下面中缀表达式的后缀表达并求值:
在这里插入图片描述

求解思路
  1. 使用正则表达式将输入字符串分割成 tokens。
['(', '-', '5', '+', '3', ')', '*', '2', '-', '4', '/', '(', '2', '-', '√', '(', '16', '-', '2', ')', ')', '+', '3', '^', '2']

遍历 tokens,使用栈来处理运算符和括号。

  1. 定义运算优先级,并根据运算符优先级决定何时将运算符加入输出或压入栈。
    def precedence(op):"""定义运算符优先级"""if op in {'+', '-'}:return 1if op in {'*', '/'}:return 2if op == '^':return 3if op == '√':return 4return 0
  1. 将运算符号和数学计算对应起来
operators = {'+': lambda x, y: x + y,'-': lambda x, y: x - y,'*': lambda x, y: x * y,'/': lambda x, y: x / y if y != 0 else float('inf'),  # 处理除以零的情况'^': lambda x, y: math.pow(x, y),'√': lambda x: math.sqrt(x) if x >= 0 else float('nan')  # 处理负数开方的情况}
  1. 计算得到的后缀表达式的值
Python3程序
import re
import mathdef infix_to_postfix(expression):def precedence(op):"""定义运算符优先级"""if op in {'+', '-'}:return 1if op in {'*', '/'}:return 2if op == '^':return 3if op == '√':return 4return 0def is_operator(token):"""检查token是否为运算符"""return token in {'+', '-', '*', '/', '^', '√'}output = []  # 用于存储后缀表达式stack = []   # 用于临时存储运算符# 使用正则表达式分割表达式为tokentokens = re.findall(r'√|\d+\.?\d*|\+|\-|\*|\/|\^|\(|\)', expression)i = 0while i < len(tokens):token = tokens[i]if token.replace('.', '').isdigit():# 处理数字if i > 0 and (tokens[i-1] == ')' or tokens[i-1].replace('.', '').isdigit()):# 在两个数字或右括号和数字之间插入乘号(处理隐式乘法)while stack and precedence(stack[-1]) >= precedence('*'):output.append(stack.pop())stack.append('*')output.append(token)elif token == '(':# 处理左括号if i > 0 and (tokens[i-1] == ')' or tokens[i-1].replace('.', '').isdigit()):# 在数字和左括号之间插入乘号(处理隐式乘法)while stack and precedence(stack[-1]) >= precedence('*'):output.append(stack.pop())stack.append('*')stack.append(token)elif token == ')':# 处理右括号while stack and stack[-1] != '(':output.append(stack.pop())if stack and stack[-1] == '(':stack.pop()  # 弹出左括号else:raise ValueError("括号不匹配")elif is_operator(token):# 处理运算符if token == '√':# 处理根号if i + 1 < len(tokens) and tokens[i+1] == '(':# 如果根号后面跟着左括号,找到匹配的右括号bracket_count = 1j = i + 2while j < len(tokens) and bracket_count > 0:if tokens[j] == '(':bracket_count += 1elif tokens[j] == ')':bracket_count -= 1j += 1if bracket_count != 0:raise ValueError("括号不匹配")# 递归处理根号内的表达式sub_expr = ''.join(tokens[i+2:j-1])sub_postfix = infix_to_postfix(sub_expr)output.extend(sub_postfix)output.append(token)i = j - 1  # 更新索引到右括号的位置else:# 如果根号后面不是左括号,按普通运算符处理while stack and precedence(stack[-1]) >= precedence(token):output.append(stack.pop())stack.append(token)else:# 处理一元减号if token == '-' and (i == 0 or tokens[i-1] == '(' or is_operator(tokens[i-1])):output.append('0')while stack and precedence(stack[-1]) >= precedence(token):output.append(stack.pop())stack.append(token)i += 1# 将栈中剩余的运算符添加到输出while stack:if stack[-1] == '(':raise ValueError("括号不匹配")output.append(stack.pop())return outputdef evaluate_rpn(tokens):"""计算后缀表达式的值"""stack = []operators = {'+': lambda x, y: x + y,'-': lambda x, y: x - y,'*': lambda x, y: x * y,'/': lambda x, y: x / y if y != 0 else float('inf'),  # 处理除以零的情况'^': lambda x, y: math.pow(x, y),'√': lambda x: math.sqrt(x) if x >= 0 else float('nan')  # 处理负数开方的情况}for token in tokens:if token in operators:if token == '√':# 处理一元运算符(开方)if not stack:raise ValueError("无效的表达式:√ 缺少操作数")a = stack.pop()result = operators[token](a)else:# 处理二元运算符if len(stack) < 2:raise ValueError(f"无效的表达式:{token} 缺少操作数")b = stack.pop()a = stack.pop()result = operators[token](a, b)stack.append(result)else:# 将数字转换为浮点数并压入栈try:stack.append(float(token))except ValueError:raise ValueError(f"无效的token: {token}")# 确保最后栈中只剩一个数(结果)if len(stack) != 1:raise ValueError("无效的表达式")return stack[0]def calculate(expression):"""主计算函数,处理异常并返回结果"""try:postfix = infix_to_postfix(expression)result = evaluate_rpn(postfix)return resultexcept Exception as e:return f"错误: {str(e)}"if __name__ == '__main__':# 测试expressions = '(-5 + 3) * 2 - 4 / (2 - √(16-2)) + 3^2'postfix = infix_to_postfix(expressions)result = evaluate_rpn(postfix)print(f"中缀表达式: {expressions}")print(f"后缀表达式: {' '.join(postfix)}")print(f"计算结果: {result}")

结果

中缀表达式: (-5 + 3) * 2 - 4 / (2 -(16-2)) + 3^2
后缀表达式: 0 5 - 3 + 2 * 4 2 16 2 -- / - 3 2 ^ +
计算结果: 7.296662954709577

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

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

相关文章

华为GaussDB数据库之Yukon安装与使用

一、Yukon简介 Yukon&#xff08;禹贡&#xff09;&#xff0c;基于openGauss、PostgreSQL、GaussDB数据库扩展地理空间数据的存储和管理能力&#xff0c;提供专业的GIS&#xff08;Geographic Information System&#xff09;功能&#xff0c;赋能传统关系型数据库。 Yukon 支…

Go基础编程 - 15 - 延迟调用(defer)

延迟调用 defer 1. 特性2. 常用用途3. defer 执行顺序&#xff1a;同函数内先进后出4. defer 闭包5. defer 陷阱 上一篇&#xff1a;泛型 1. 特性 1. 关键字 defer 用于注册延迟调用。 2. defer 调用直到 return 前才被执行。 3. 同函数内多个 defer 语句&#xff0c;按先进后…

怎么绕开华为纯净模式安装软件

我是标题 众所周不知&#xff0c;华为鸿蒙系统自带纯净模式&#xff0c;而且 没法关闭 : ) 我反正没找到关闭键 以前或许会有提示&#xff0c;无视风险&#xff0c;“仍要安装”。但我这次遇到的问题是&#xff0c;根本没有这个选项&#xff0c;只有“应用市场”和“取消”&…

数据结构:二叉树的遍历和线索二叉树

二叉树的遍历 二叉树的遍历是二叉树的一种重要的操作&#xff0c;指按照某种顺序访问树中的每个节点&#xff0c;并且每个节点仅被访问一次。常见的遍历方式有四种&#xff1a;前序遍历、中序遍历、后序遍历和层次遍历&#xff08;或称为广度优先遍历&#xff09;。 二叉树的…

物联网系统中LCD屏主流驱动方案详解

01 物联网系统中为什么要使用LCD驱动芯片 在物联网系统中使用LCD驱动芯片的原因主要有以下几点&#xff1a; 节省资源 1、减少IO端口占用&#xff1a;在物联网设备中&#xff0c;单片机或其他主控芯片的IO资源通常非常有限。LCD驱动芯片可以通过简单的接口&#xff08;如SP…

基于Hive和Hadoop的白酒分析系统

本项目是一个基于大数据技术的白酒分析系统&#xff0c;旨在为用户提供全面的白酒市场信息和深入的价格分析。系统采用 Hadoop 平台进行大规模数据存储和处理&#xff0c;利用 MapReduce 进行数据分析和处理&#xff0c;通过 Sqoop 实现数据的导入导出&#xff0c;以 Spark 为核…

jenkins项目发布基础

随着软件开发需求及复杂度的不断提高,团队开发成员之间如何更好地协同工作以确保软件开发的质量已经慢慢成为开发过程中不可回避的问题。Jenkins 自动化部署可以解决集成、测试、部署等重复性的工作,工具集成的效率明显高于人工操作;并且持续集成可以更早的获取代码变更的信息,…

从Linux系统的角度看待文件-基础IO

目录 从Linux系统的角度看待文件 系统文件I/O open write read 文件操作的本质 vim中批量注释的方法 从Linux系统的角度看待文件 关于文件的共识&#xff1a; 1.空文件也要占用磁盘空间 2.文件内容属性 3.文件操作包括文件内容/文件属性/文件内容属性 4.文件路径文…

【Qt】前后端交互---DataCenter类

设计目的 前后端交互系统中&#xff0c;创建并使用数据核心类的目的就是让该类作为客户端的数据中心&#xff0c;也就是说其负责管理客户端的所有数据与服务器的网络通信。 数据持久化 初始化数据文件 该函数设计的目的就是用于检查所需要的文件和目录是否存在&#xff0c;如…

短视频矩阵系统源码开发/矩阵系统OEM搭建--源代码开发经验分享

短视频矩阵系统开发策略 短视频矩阵系统源码的原生开发方法 一、基于原生技术的短视频矩阵系统开发途径 原生编程语言&#xff1a;采用各平台专有的编程语言及开发工具&#xff0c;如iOS平台的Swift或Objective-C&#xff0c;以及平台的Java或Kotlin&#xff0c;确保应用性能与…

[贪心+数学/数学+位运算] 两种方法O(1)解决 消减整数

标题&#xff1a;[贪心数学/数学位运算] 两种方法O(1)解决 消减整数 个人主页水墨不写bug 目录 一、题目&#xff1a;消减整数(Newcoder) 二、题目分析 1.理解题意&#xff1a; 2.解决问题 解法详解一&#xff1a;贪心数学 解法一参考代码&#xff1a; 解法详解二&#xf…

WiFi无线连接管理安卓设备工具:WiFiADB

介绍 WiFi ADB 使您能够通过 WiFi TCP/IP 连接直接在设备上轻松调试和测试 Android 应用&#xff0c;无需使用 USB 数据线。在启用 WiFi 上的 ADB 后&#xff0c;打开控制台将电脑连接到设备。 手机和电脑在同一个WiFi然后电脑上运行adb connect x.x.x.x:x命令即可 下载 谷…

MindSearch 部署到Github Codespace 和 Hugging Face Space

和原有的CPU版本相比区别是把internstudio换成了github codespace。 教程是https://github.com/InternLM/Tutorial/blob/camp3/docs/L2/MindSearch/readme_github.md 复现步骤&#xff1a; 根据教材安装环境和创建硅基流动 API 然后启动前后端 然后按照教材部署到 Huggi…

一站式家装服务管理系统

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本一站式家装服务管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数…

基于Hive和Hadoop的病例分析系统

本项目是一个基于大数据技术的医疗病历分析系统&#xff0c;旨在为用户提供全面的病历信息和深入的医疗数据分析。系统采用 Hadoop 平台进行大规模数据存储和处理&#xff0c;利用 MapReduce 进行数据分析和处理&#xff0c;通过 Sqoop 实现数据的导入导出&#xff0c;以 Spark…

《征服数据结构》哈夫曼树(Huffman Tree)

摘要&#xff1a; 1&#xff0c;哈夫曼树的介绍 2&#xff0c;哈夫曼树的构造 3&#xff0c;哈夫曼树带权路径长度计算 4&#xff0c;哈夫曼树的编码 5&#xff0c;哈夫曼树的解码 1&#xff0c;哈夫曼树的介绍 哈夫曼树(Huffman Tree)也叫霍夫曼树&#xff0c;或者赫夫曼树&am…

学校周赛(1)

A - Short Sort 题目&#xff1a; 思路&#xff1a; 本条题目只允许改一处地方&#xff0c;只有三个字母&#xff0c;我们可以直接枚举所有移动过的结果&#xff0c;同时使用哈希去记录其值&#xff0c;对于每一个输入我们都寻找是否有这个值记录&#xff0c;有则输出YES否则…

微深节能 环形运动机械定位控制系统 格雷母线

微深节能的环形运动机械定位控制系统中的格雷母线&#xff0c;是一种高精度、无磨损的非接触式位置检测系统&#xff0c;特别适用于环形运动机械的定位控制。该系统主要由格雷母线、天线箱、电气柜等关键部件组成&#xff0c;其核心在于格雷母线这一特殊的编码线。 格雷母线概述…

JAVA一站式台球学习平台多端畅享助教教练系统小程序源码

​一站式台球学习平台 —— 多端畅享助教教练系统 &#x1f31f;【开篇&#xff1a;解锁台球新境界】&#x1f31f; 你是否厌倦了传统台球学习的枯燥与局限&#xff1f;想要随时随地&#xff0c;都能享受专业级的台球指导吗&#xff1f;今天&#xff0c;就让我为你揭秘一款颠覆…

JITWatch安装使用方法

JITWatch 版本1.4.2 JDK 版本 11以上 1.下载JITWatch&#xff1a; https://github.com/AdoptOpenJDK/jitwatch/releases/download/1.4.2/jitwatch-ui-1.4.2-shaded-win.jar 2.启动 bat脚本执行&#xff1a;通过启动jar包方式启动JITWatch echo off start cmd /c "ti…