当前位置: 首页 > news >正文

Java 实现括号匹配:栈的应用与优化

Java 实现括号匹配:栈的应用与优化

在编程中,括号匹配问题是一个常见的题目,尤其在编写表达式解析器时,正确地识别和匹配括号是至关重要的。本文将讨论如何使用 Java 实现括号匹配,并展示如何通过使用不同的栈实现进行优化。

题目描述

给定一个只包含括号的字符串,判断字符串中的括号是否有效。有效的括号需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。

例如:

  • "()""()[]{}" 是有效的括号字符串。
  • "(]""([)]" 是无效的括号字符串。
基础实现:使用 Stack

Java 提供了 Stack 类来支持栈的基本操作。以下代码展示了如何使用 Stack 类来实现括号匹配。

public boolean isValid(String s) {Stack<Character> stack = new Stack<>();for (char c : s.toCharArray()) {// 如果字符是左括号(小括号、大括号或方括号)if (c == '(' || c == '{' || c == '[') {// 将左括号压入栈中stack.push(c);} else {// 如果栈为空,则返回false,表示括号不匹配if (stack.isEmpty()) return false;// 弹出栈顶元素char top = stack.pop();// 判断右括号与栈顶元素是否匹配if (c == ')' && top != '(' ||c == '}' && top != '{' ||c == ']' && top != '[') return false;}}// 如果栈为空,表示所有括号都匹配成功,返回true;否则返回falsereturn stack.isEmpty();
}
代码分析
  1. 使用栈存储左括号:当遇到左括号时,将其压入栈中。
  2. 匹配右括号:当遇到右括号时,检查栈是否为空。如果为空,则说明没有对应的左括号,返回 false。否则,弹出栈顶元素并检查其是否与当前的右括号匹配。
  3. 最终判断:遍历完成后,如果栈为空,则说明所有的括号都已匹配,返回 true;否则返回 false
优化实现:使用 ArrayDeque 代替 Stack

虽然 Stack 是直接支持栈操作的类,但在性能上可以使用 ArrayDeque 来替代它。ArrayDeque 是一个双端队列,但也可以用作栈,且比 Stack 更高效。

使用 ArrayDeque 的代码实现
public boolean isValid(String s) {Deque<Character> stack = new ArrayDeque<>();for (char c : s.toCharArray()) {// 如果字符是左括号(小括号、大括号或方括号)if (c == '(' || c == '{' || c == '[') {// 将左括号压入栈中stack.push(c);} else {// 如果栈为空,则返回false,表示括号不匹配if (stack.isEmpty()) return false;// 弹出栈顶元素char top = stack.pop();// 判断右括号与栈顶元素是否匹配if (c == ')' && top != '(' ||c == '}' && top != '{' ||c == ']' && top != '[') return false;}}// 如果栈为空,表示所有括号都匹配成功,返回true;否则返回falsereturn stack.isEmpty();
}
优化效果

ArrayDeque 提供了比 Stack 更好的性能表现,尤其在频繁的压入和弹出操作下。虽然两者在 API 上看似相同,但在底层实现上,ArrayDeque 基于数组而非同步的栈,因而避免了线程安全带来的额外开销。

总结

本文介绍了如何使用 Java 的 Stack 类和 ArrayDeque 类来实现括号匹配,并解释了其中的代码逻辑。通过使用 ArrayDeque 替代 Stack,我们可以进一步提升代码的性能。

对于初学者来说,掌握这些基础的数据结构和算法是至关重要的。希望这篇博客能够帮助你理解如何处理括号匹配问题,以及如何在 Java 中有效地使用栈来解决类似问题。

相关文章:

  • zabbix的主/动模式自定义监控项
  • LCM红外小目标检测
  • 【人工智能】Transformers之Pipeline(八):文生图/图生图(text-to-image/image-to-image)
  • C语言之“ 分支和循环 ” (2)
  • 阿里云CDN-边缘脚本EdgeScript的CI/CD实践
  • MTK Android12 SystemUI 手势导航 隐藏导航栏底部布局
  • Tomcat 使用和配置文件(详解)
  • Spring Boot - 通过ServletRequestHandledEvent事件实现接口请求的性能监控
  • <数据集>停车场空位识别数据集<目标检测>
  • LabVIEW位移检测系统
  • 【CPP】slt-list由认识到简化模拟实现深度理解~
  • 储能集装箱动环监控系统,动环监控在集装箱的应用方案@卓振思众
  • 安科瑞Home EMS:引领家庭光储新纪元,让每一度电都尽在掌握
  • 旋转图像
  • Linux驱动开发—平台总线模型详解
  • JavaScript-如何实现克隆(clone)函数
  • 【跃迁之路】【735天】程序员高效学习方法论探索系列(实验阶段492-2019.2.25)...
  • ES6 学习笔记(一)let,const和解构赋值
  • Laravel Mix运行时关于es2015报错解决方案
  • LeetCode刷题——29. Divide Two Integers(Part 1靠自己)
  • pdf文件如何在线转换为jpg图片
  • socket.io+express实现聊天室的思考(三)
  • 工作中总结前端开发流程--vue项目
  • 前端
  • 一份游戏开发学习路线
  • 原生 js 实现移动端 Touch 滑动反弹
  • 主流的CSS水平和垂直居中技术大全
  • Salesforce和SAP Netweaver里数据库表的元数据设计
  • Unity3D - 异步加载游戏场景与异步加载游戏资源进度条 ...
  • 你学不懂C语言,是因为不懂编写C程序的7个步骤 ...
  • ​Redis 实现计数器和限速器的
  • ​马来语翻译中文去哪比较好?
  • (C语言)共用体union的用法举例
  • (react踩过的坑)antd 如何同时获取一个select 的value和 label值
  • (八)光盘的挂载与解挂、挂载CentOS镜像、rpm安装软件详细学习笔记
  • (超详细)语音信号处理之特征提取
  • (仿QQ聊天消息列表加载)wp7 listbox 列表项逐一加载的一种实现方式,以及加入渐显动画...
  • (附源码)计算机毕业设计SSM在线影视购票系统
  • (面试必看!)锁策略
  • (七)c52学习之旅-中断
  • (算法二)滑动窗口
  • (五)Python 垃圾回收机制
  • (一)springboot2.7.6集成activit5.23.0之集成引擎
  • (一一四)第九章编程练习
  • (原創) 人會胖會瘦,都是自我要求的結果 (日記)
  • (原創) 如何讓IE7按第二次Ctrl + Tab時,回到原來的索引標籤? (Web) (IE) (OS) (Windows)...
  • (转) 深度模型优化性能 调参
  • * 论文笔记 【Wide Deep Learning for Recommender Systems】
  • .NET Compact Framework 3.5 支持 WCF 的子集
  • .NET Micro Framework初体验
  • .net 无限分类
  • .NET8 动态添加定时任务(CRON Expression, Whatever)
  • .NET教程 - 字符串 编码 正则表达式(String Encoding Regular Express)
  • .NET设计模式(2):单件模式(Singleton Pattern)
  • .net之微信企业号开发(一) 所使用的环境与工具以及准备工作