栈的应用-有效的括号

熵桥流沙
• 阅读 2346

有效的括号

编写程序时, 一个类, 函数, 表达式, 都需要括号匹配,如果括号没有正确匹配,编译器就会报错, 这其实一种是数据结构--栈的应用.

栈(Stack)

是一种线性结构
只能从一端添加元素,也只能从同一端取出元素,这一端称为栈顶
栈的应用-有效的括号
后进先出的特性(LIFO-last in first out):最后插入的元素最先出来.

这种后进先出的特性十分有用,便于理解栈的实际应用,举如下两个例子:

  • 无处不在的Undo操作(撤销)
    编辑器中的撤销原理就是运用了栈先进后出的特性,栈顶存放了你最近一次的操作,撤销会将这次操作的内容弹出栈顶
  • 程序调用的系统栈
    程序在进行子过程调用的时候,当一个子过程执行完成之后,可以自动的回到上层调用中断的位置继续执行下去

栈的应用-有效的括号

  1. 函数A()在执行到第2行时调用了函数B(),
    栈中记录下A2(表示函数A()在第2行时中断);
  2. 进入函数B(),执行到第2行时调用函数C(),
    栈中记录下B2(表示函数B()在第2行时中断);
  3. 进入函数C()一直到执行完毕,cpu不知道下一步该执行哪行代码,到系统栈中查看,最近一次中断的地方是函数B()第2行,返回去执行,到函数A()也是如此,执行完毕.

下面说说括号匹配的题目

leetcode有这样一题,我们可以参照它来理解这个概念
leetcode第20题:有效的括号

题目:
给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。

有效字符串需满足:

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

来源:力扣 (LeetCode)

栈的应用-有效的括号
首先声明一个栈,

然后逐一遍历这个括号字符串,如果是左括号就将它压入栈;

如果是右括号,此时查看栈顶的元素是否与之匹配,如果匹配成功,栈顶的元素就要出栈;

如果最后栈中的元素被清空,证明这串括号是有效的;

如果匹配失败,那么就证明了这串括号是错误的.

栈顶元素反应了在嵌套的层次关系中,最近的需要匹配的元素

标准答案代码实现:

import java.util.HashMap;
import java.util.Stack;
//有效的括号
public class Solution {
    //负责映射的哈希表
    private HashMap<Character,Character> mappings;

    //构造时初始化哈希表,使代码更具可读性
    public Solution(){
        this.mappings = new HashMap<>();
        this.mappings.put(')', '(');
        this.mappings.put('}', '{');
        this.mappings.put(']', '[');
    }

    public boolean isValid(String s){
        //声明一个栈
        Stack<Character> stack = new Stack<>();
        //遍历字符串
        for (int i = 0; i < s.length(); i++){
            char c = s.charAt(i);

            //如果当前字符串是右括号
            if (this.mappings.containsKey(c)){
                //获取栈的顶部元素。如果栈是空的,设置一个哑值'#'
                char topElement = stack.empty() ? '#' : stack.pop();

                //如果此括号的映射与栈的顶部元素不匹配,则返回false。
                if (topElement != this.mappings.get(c)){
                    return false;
                }
            }else {
                //如果当前字符是左括号,push到栈中
                stack.push(c);
            }
        }
        //如果堆栈仍然包含元素,那么它是一个无效的表达式。
        return stack.isEmpty();
    }

}

简易版:

简易版:
import java.util.Stack;
//有效的括号
public class Solution {

    public boolean isValid(String s){
        //声明一个栈
        Stack<Character> stack = new Stack<>();
        for (int i = 0; i < s.length(); i++){//遍历字符串
            char c = s.charAt(i); //转存为char
            if (c == '(' || c == '[' || c == '{'){
                //如果是左括号就push进去
                stack.push(c);
            }else {//否则检查是否与栈顶元素匹配
                if (stack.isEmpty())
                    return false;

                //将栈顶元素弹出
                char topChar = stack.pop();
                //如果并不能匹配返回false
                if (c == ')' && topChar != '(')
                    return false;
                if (c == ']' && topChar != '[')
                    return false;
                if (c == '}' && topChar != '{')
                    return false;
            }
        }
        //最后检查栈是否为空
        return stack.isEmpty();
    }

}

结合自己的理解记录了学习的过程
图片来自网络

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
4年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
似梦清欢 似梦清欢
3年前
栈和队列
栈原理栈(stack)又名堆栈,是一种只能在表尾进行插入和删除操作的线性表。能够进行操作的这一端被称为栈顶,相对地,把另一端称为栈底。:::warning栈内元素操作时先进后出,类似于电梯上下成员,最后进去的人最先出
Wesley13 Wesley13
4年前
Java实现顺序栈
一、分析  栈是限定仅在表的一端进行插入或删除操作的线性表,对于栈来说,操作端称为栈顶,另一端则称为栈底,栈的修改是按照后进先出的原则进行的,因此又称为后进先出的线性表。  顺序栈是指利用顺序存储结构实现的栈,即利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素,同时附设指针top指示栈顶元素在顺序栈中的位置。  一个标准的顺序栈
Stella981 Stella981
4年前
JVM 字节码指令表
字节码助记符指令含义0x00nop什么都不做0x01aconst\_null将null推送至栈顶0x02iconst\_m1将int型1推送至栈顶0x03iconst\_0将int型0推送至栈顶0x04iconst\_1将int型1推送至栈顶0x05ic
Wesley13 Wesley13
4年前
20165322 第一周结队编程
结队编程四则运算阶段总结学习笔记中缀表达式转换为后缀表达式如果遇到数字,我们就直接将其输出。如果遇到非数字时,若栈为空或者该符号为左括号或者栈顶元素为括号,直接入栈。如果遇到一个右括号,持续出栈并输出符号
菜园前端 菜园前端
2年前
什么是栈?
原文链接:栈是基础数据结构,栈是一种遵循后进先出原则的有序集合,添加新元素的一端称为栈顶,另一端称为栈底。操作栈的元素时,只能从栈顶操作(添加、移除、取值)。实现功能在JavaScript中没有栈,但是可以通过Array实现栈的所有功能push()入栈po
Python进阶者 Python进阶者
2年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
贾蔷 贾蔷
6个月前
洛谷P10472题解:使用栈高效求解最长有效括号子串
一、问题描述给定一个包含'('、')'、',找出其中最长的有效括号子串的长度。有效括号子串需要满足括号正确匹配且连续。二、核心思想1.的巧妙应用:使用栈记录未匹配括号的位置1.边界处理:初始时压入1作为虚拟边界1.动态更新:每次匹配成功时计算当前有效长度三