栈——解决括号匹配问题

本文详细介绍了栈这种数据结构在处理字符串问题上的应用,如判断回文、检查算术表达式括号匹配、实现字符串的结构化转换等。通过具体的JavaScript代码示例,阐述了如何利用栈解决这些问题,揭示了栈的‘后进先出’特性在解决此类问题中的关键作用。
摘要由CSDN通过智能技术生成


前言

常会碰到这样一类问题,例如:

//1.编写一个函数,接收一个算数表达式作为参数,返回括号的缺失位置
1.3+2 * 3 +(52%5
//2.实现一个normallize函数,将字符串转换为特定的数据结构
 [a[b[c]]]//转换为{value:a,children:{value:b,children:{value:c}}

那么今天就来总结一下这类题目的解题思路:

一、栈是什么?

栈是一种特殊的列表,栈内的元素只能通过列表的一端进行访问,这一段端称为栈顶。(先进后出)

对栈的操作主要是将一个元素压入栈和将一个元素弹出栈。入栈使用push()方法,出栈使用pop()方法。

二、栈的应用

1.判断是否是回文

function isPalindrome(str) {
	let s = str.slice('');
    let rts ='';
    while(s.length>0) {
        rts+=s.pop();//出栈
    }
    if(str === rts) {
        return true;
    } else {
        return false;
    }
}

2.编写一个函数,该函式接收一个算数表达式作为参数,返回括号缺失的位置

function demo (str) {
  let sign = '(){}[]'
  let s = []
  for (let i = 0; i < str.length; i++) {
    if (sign.includes(str[i])) {
      let val = str[i];
      switch (val) {
        case '(':
        case '[':
        case '{': s.push(val); break;
        case ')':
          let map1 = s.pop();
          if (map1 !== '(') {
            return `位置${i}的)不匹配`
          }
          break;
        case ']':
          let map2 = s.pop();
          if (map2 !== '[') {
            return `位置${i}的]不匹配`
          }
          break;
        case '}':
          let map3 = s.pop();
          if (map3 !== '{') {
            return `位置${i}的}不匹配`
          }
          break;
      }
    }
  }
  if (s.length) {
    return `符号${s.join()}没有闭合`
  } else {
    return '符号正确'
  }
}

3.js实现括号匹配问题:

给定一个只包括“{”,“}”,“(”“)”,“[“ ,”]’’的字符串,判断字符串是否有效。有效字符串需要满足:

  • 左括号必须用相同类型的右括号闭合
  • 左括号必须以正确的顺序闭合(不得出现嵌套)

注意空字符串可被认为是有效的字符串;

算法流程:

  1. 遍历字符串的每一个字符

  2. 如果是左括号直接push入栈

  3. 如果是右括号,将栈顶的第一个元素取出来与当前的元素进行对比,如果不匹配,则return false;如果匹配那么就出栈

  4. 遍历完之后保证栈内为空

问题3和问题2实际是没有区别的,用上面的方法完全可以求解这个问题。但是我们现在用面向对象的思维来看这道题。

//   定义栈的类
      class Stack {
        constructor() {
          this.stack = [];
        }
        push(item) {
          return this.stack.push(item);
        }
        pop() {
          return this.stack.pop();
        }
        // 查询栈顶的元素
        peek() {
          return this.stack[this.getSize() - 1];
        }
        //返回栈的长度
        getSize() {
          return this.stack.length;
        }
        // 栈的非空判断
        isEmpty() {
          return this.getSize() === 0;
        }
      }
      function testIsValid(str) {
        // 以左右括号来建立一个对象,key为左括号,value为右括号
        var Map = {
          "{": "}",
          "(": ")",
          "[": "]",
        };
        //实例化一个栈
        const myStack = new Stack();
        //遍历str字符串
        for (let v of str) {
          if (Map[v]) {
            myStack.push(v); //是左括号,入栈
          } else if (Object.values(Map).includes(v)) {
            // 右括号  将当前的元素和栈顶的第一个元素进行匹配
            let last = myStack.pop();
            if (v !== Map[last]) return false;
          } else {
          //这里排除的是空字符的情况,如果不是左右括号而是其他的空字符串或者非法字符的话,将终止本次循环,执行下一次循环
            continue;
          }
        }
        //遍历完成之后要保证栈内要为空
        return myStack.getSize() === 0;
      }

4.实现一个normalize函数,能将特定的字符串转换为特定的结构化数据(阿里笔试题)

//例如将[a[b[c]]]转换为{ value: 'a', children: { value: 'b', children: { value: 'c' } } }
function normalize (str) {
  let s = []; // 临时存储
  let list = [];// 存储匹配的括号的下标
  let obj = {}//存储结果
  for (let i = 0; i < str.length; i++) {
    let value = str[i]
    switch (value) {
      case '[':
        s.push(i)break;
      case ']':
        list.unshift([s.pop(), i])default:
        break;
    }
  }
  let [start, end] = list[0]let parent = obj;
  for (let i = 1; i < list.length; i++) {
    let [a, b] = list[i];
    let result = str.slice(start + 1, a) + str.slice(b + 1, end);
    start = a;
    end = b;
    parent.value = result;
    parent.children = {};
    parent = parent.children;
  }
  // 处理list最后一个元素
  let [x, y] = list[list.length - 1];
  parent.value = str.slice(x + 1, y)return obj;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值