年初面试的时候碰到过一道笔试题,要求实现一个函数来判断字符串中括号是否匹配
例如:以下字符串均为括号匹配的:(){()[{}]}()({}){()}[]{()}[{{()}}],以下字符串不匹配:({)}
我最开始想到的是正则方法,如下:
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更新---------
正则比栈方法要慢的其实,感谢 @糖醋丸子 的指正
有不同见解欢迎评论区提出