古語有云:“事以密成,語以泄敗”!
關于字符串解碼:
- 題目:
- 題解:
- js代碼:
- 代碼中遇到的方法:
- repeat方法:
- 為什么這里不用this.strstack.push(result)?
題目:
題解:
假設輸入字符串為 s = “3[a2[c]]”,解碼過程如下:
- 初始化變量?:
numStack:一個數組,用于存儲遇到的數字(表示重復次數)。
strStack:一個數組,用于存儲待拼接的字符串片段。
num:一個變量,用于臨時存儲當前解析到的數字(倍數)。
result:一個字符串,用于臨時存儲當前構建的字符串結果。 - 掃描到 3,num = 3。
- 掃描到 [,將 result = “” 推入 strStack,將 num = 3 推入 numStack,然后重置 result = “” 和 num = 0。
- 掃描到 a,追加到 result,result = “a”。
- 掃描到 2,num = 2。
- 掃描到 [,將 result = “a” 推入 strStack,將 num = 2 推入 numStack,然后重置 result = “” 和 num = 0。
- 掃描到 c,追加到 result,result = “c”。
- 掃描到 ],從 numStack 彈出 2,從 strStack 彈出 “a”,構建子串 “ac”.repeat(2) = “acc”,然后 result = “acc”。
- 掃描到 ],從 numStack 彈出 3,構建最終字符串 “acc”.repeat(3) = “accaccacc”。
- 因此,decodeString(“3[a2[c]]”) 的返回值是 “accaccacc”。
也就是有四條分支, 分別是 如果是數字 、[ 、 ] 、 字符串的情況。
? 1. 處理數字字符?:如果 char 是一個數字(!isNaN(char)),則將其轉換為數字,并累加到 num 上。這里使用了 num = num * 10 + Number(char); 來處理多位數字。
?2. 處理 [ 字符?:如果遇到 [,表示一個重復模式的開始。將當前的 result 字符串推入 strStack,以便稍后在其后追加重復的字符串。將當前的 num(表示重復次數)推入 numStack。重置 result 和 num 為空或零,為處理新的字符串片段和可能的數字做準備。
?3. 處理 ] 字符?:如果遇到 ],表示一個重復模式的結束。從 numStack 彈出重復次數 repeatTimes。從 strStack 彈出之前保存的字符串片段,并將其與當前 result 字符串的 repeatTimes 次重復結果拼接起來,然后存回 result。
?4. 處理普通字符?:如果 char 不是數字、[ 或 ],則將其追加到 result 字符串的末尾。
js代碼:
/*** @param {string} s* @return {string}*/
var decodeString = function(s) {let numStack = [];let strStack = [];let num = 0;let result = "";for(let char of s){if(!isNaN(char)){num = num * 10 + Number(char); }else if(char == '['){strStack.push(result);numStack.push(num);num = 0;result = "";}else if(char == ']'){let reapTime = numStack.pop();result = strStack.pop() + result.repeat(reapTime);}else{result += char;}}return result;};
代碼中遇到的方法:
repeat方法:
在JavaScript中,repeat方法是String對象的一個內置方法,它用于將一個字符串重復指定次數,并返回一個新的字符串。這個方法不會改變原始字符串,而是創建一個新的字符串作為結果。
舉例:
let originalString = "abc";
let repeatedString = originalString.repeat(3);
console.log(repeatedString); // 輸出 "abcabcabc"
寫法:
str.repeat(count)
count:一個整數,表示字符串應該被重復的次數。如果count是0,則返回一個空字符串。如果是負數,會拋出一個RangeError異常。
返回值:
一個包含原始字符串重復count次的新字符串。
注意事項:
- 如果count是一個小數,它會被自動轉換為整數,小數部分會被舍棄。
- 如果count是Infinity或者是一個大于Number.MAX_SAFE_INTEGER(即253 - 1)的數,會拋出RangeError,因為JavaScript無法處理這么大的字符串。
- repeat方法是一個不可變的操作,它不會修改原始字符串,而是返回一個新的字符串。
舉例二:
// 使用repeat方法生成一個由10個"-"組成的字符串(分隔符)
let dashes = "-".repeat(10);
console.log(dashes); // 輸出 "----------"// 使用repeat方法和模板字符串生成一個帶有邊框的文本
let text = "Hello, world!";
let borderedText = `|${text.repeat(3)}|`;
console.log(borderedText); // 輸出 "|Hello, world!Hello, world!Hello, world!|"
為什么這里不用this.strstack.push(result)?
this關鍵字通常用于訪問對象的屬性或方法。然而,decodeString函數代碼中,并沒有使用this來引用任何對象的屬性或方法,而是直接使用了局部變量strStack。因為strStack是在函數內部定義的,作為函數作用域內的一個變量,它不需要通過this來訪問。
這里有幾種情況可能會讓你看到this.strStack這樣的用法:
- 對象的方法?:如果strStack是某個對象的屬性,并且正在該對象的方法內部訪問它,那么會使用this.strStack。但在代碼中,strStack是一個局部變量,不是對象的屬性。
- 類的成員變量?:在ES6及更高版本的JavaScript中,如果在一個類的方法內部訪問類的成員變量(即屬性),也會使用this。但在代碼中,并沒有使用類。
- 閉包或上下文改變?:在某些情況下,可能會看到函數內部的this被用來引用外部上下文(比如,在回調函數或箭頭函數中,this的值可能會根據它是如何被調用的而改變)。但在decodeString函數中,并沒有這樣的上下文改變。