驗證()、{}、[]三種括號是否成對出現的方法(利用壓棧彈棧實現)
阿新 • • 發佈:2020-11-29
原文連結:https://blog.csdn.net/mrdeng_web2018/article/details/108426604
近期遇到個問題,需要驗證使用者輸入的字串中(),小括號是否匹配,是否成對,順序對不對。
我的需求雖然是隻需要考慮到(),是否匹配,但作者把[]、{}也順帶實現了,若果只需要檢測某一種括號,將map裡的鍵值對去掉多餘的即可,很棒!
我用的是vue專案,所以直接寫成工具
bracketMatch.js
// 定義棧的類 class bracketMatchStack { 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; } } exportfunction testBracketIsValid(str) { // 以左右括號來建立一個物件,key為左括號,value為右括號 var Map = { "{": "}", "(": ")", "[": "]", }; //例項化一個棧 const myStack = new bracketMatchStack(); //遍歷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; }
在專案中使用:
引入
import {testBracketIsValid} from "@/utils/bracketMatch"
使用:
str1 :"(dfsdfsdfsd)dasdadas()(())", str2:"(dgdfdgfd(fgdgfd)", str3 :"(dfsdfsdfsd)dasdadas()(({}))", str4:"[dgdfdgfdfgdgfd]", str5:")(", str6:"()(",
console.log(testBracketIsValid(this.str1));//true console.log(testBracketIsValid(this.str2));//false console.log(testBracketIsValid(this.str3));//true console.log(testBracketIsValid(this.str4));//true console.log(testBracketIsValid(this.str5));//false console.log(testBracketIsValid(this.str6));//false
總結:
很多人說用了棧的先進後出特點,但是我覺得對於一個純前端來說,一直就用js,說棧顯的有點深奧,對新手不友好,(先進後出,我覺得是很正常的,還原理什麼,有點深奧,相信一直使用js的人,不需要去解釋這一點,這一切都很自然,不需要用棧來解釋)。
壓棧其實就是陣列的push方法(想陣列最後新增元素),彈出棧,就是pop方法(去除陣列內的最後一位元素)。
用for of遍歷字串,遇見左括號就將左括號push進去(說棧也可以說陣列也行)。遇到右括號,就將陣列最後的左括號pop出去(彈出);如果當前的右括號與彈出的括號不是一個型別則返回false,這可以確定,括號的匹配有問題了,就返回false。如果遇到不是括號的元素直接結束本次迴圈,繼續下一次迴圈(continue)。最後,看看陣列內是否清除乾淨,如果不乾淨,陣列長度部位0,代表括號不是成對出現的,是奇數,返回false。這樣就可以檢驗括號是否成對出現以及匹配是否正確,感謝作者的文章,讓我拓寬點小技能。
。