js括号匹配问题

753 阅读1分钟

年初面试的时候碰到过一道笔试题,要求实现一个函数来判断字符串中括号是否匹配

例如:以下字符串均为括号匹配的:(){()[{}]}()({}){()}[]{()}[{{()}}],以下字符串不匹配:({)}

我最开始想到的是正则方法,如下:

const isMatch = (str) => {
  console.time();
  const reg = /(\(\))|(\{\})|(\[\])/g;
  let temp = str.replace(reg,'');
  while(reg.test(temp)) {
    temp = temp.replace(reg,'');
  }
  console.timeEnd();
  return !temp
}

这样一次次通过正则替换,当结束循环时若字符串长度为0即返回true

还有一种是借鉴栈的后进先出模式,如下:

const isMatch = (str) => {
  console.time();
  const rightBrackets=[')',']','}'];
  const obj = {
    '{':'}',
    '[':']',
    '(':')',
  }
  const arr = str.split('');
  let stack = [];
  const flag = arr.every(item => {
    if(rightBrackets.includes(item)) {
      if(!stack.length) return false;
      return obj[stack.pop()] === item;
    }
    stack.push(item);
    return true;
  });
  console.timeEnd();
  return !stack.length && flag;
}

只需要一次遍历即可,将stack当作一个栈,遇到左侧括号则存入数组,遇到右侧匹配括号则取出,字符串符合匹配要求的话,最终stack将恢复为空数组。

查看执行时间发现正则方法比后面的方法快,字符串越大重复字段越多差距越明显~正则yyds

----------2022.3.2更新---------

正则比栈方法要慢的其实,感谢 @糖醋丸子 的指正

有不同见解欢迎评论区提出