在codewars上作了一道括号匹配的题目。javascript
判断字符串中的{}、[]、()三种括号是否匹配,须要考虑嵌套的状况。java
例子:正则表达式
validBraces("(){}[]") // true validBraces("(}") // false validBraces("[(])") // false validBraces("([{}])") // true
这个问题的最根本只有两种状况,一种是并列的,即没有嵌套的状况,如()[]{}
;另外一种状况就是嵌套的状况,如{[()]}
。第一种状况是比较简单的,有难度的是第二种状况。存在嵌套的状况的解决方法,是首先匹配最里面的括号对,即咱们常说的从内部开始瓦解。数据结构
第一种方法:code
function validBraces(braces){ while(/\(\)|\[\]|\{\}/g.test(braces)){ braces = braces.replace(/\(\)|\[\]|\{\}/g,"") } return !braces.length; }
这种方法,查找成对的括号,而后将成对相邻的括号替换成空字符串,也就是说删除。最后判断字符串的长度是否为0。是,则表示彻底匹配,不然,比匹配。
其实,这种方案就是典型的“从内部开始瓦解”。咱们以{[()]}
为例,你观察一下,如今只有最里面的()
才是成对且相邻的,当把()
替换成空字符串以后,[]
变成了成对且相邻的,而后再将其替换成空字符串。就这样一直循环地查找,直到再也找不到成对且相邻的括号为止。ip
第二种方法:字符串
function validBraces(braces){ let leftBraReg = /[\(\{\[]/, // 栈 stack = [], bracket, rightBracket braces = braces.split('') for(bracket of braces) { if(leftBraReg.test(bracket)) { stack.push(bracket) } else { switch (bracket) { case ')': rightBracket = stack.pop() if(rightBracket !=='(') { return false } break case ']': rightBracket = stack.pop() if(rightBracket !=='[') { return false } break case '}': rightBracket = stack.pop() if(rightBracket !=='{') { return false } break } } } return stack.length === 0 ? true : false }
这种方法,是将左半边括号,即(
、[
、{
存入栈stack中,当遍历到右半边括号,即)
、]
、}
的时候,stack执行出栈操做,而后将出栈的左半边括号与遍历到的有半边括号匹配,看是否为与其相匹配的另半边括号。若是遍历完了,则判断栈的长度,为0,则匹配,不然,比匹配。
咱们一样以{[()]}
为例,前三项,即{
、[
、(
入栈,当遍历到)
的时候,位于栈顶的'('后出栈与)
比较,看是否匹配。后面的]
、}
也是同样道理。get
如今渐渐发现,数据结构和正则表达式很是重要(这里的解决方法就分别用到了),虽然平时用得少,到一道有应用场景,你就会发现数据结构和正则表达式的强大了。it