在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