大家好,我是考100分的小小码 ,祝大家学习进步,加薪顺利呀。今天说一说字符串解码[括号匹配问题怎么解决_json字符串带括号,希望您对编程的造诣更进一步.
前言
对于括号匹配问题,典型的解法就算递归进行括号匹配,当然也可以栈模拟。在此基础上才能完成额外的操作,解答任何括号匹配问题。
一、字符串解码
二、括号匹配问题
1、栈模拟–从左到右
// 字符串解码
public class DecodeString {
/* 括号匹配问题,可以递归,也可栈模拟。 */
// 栈模拟
/* 栈中存stringbuilder。 碰到‘[’时,入栈一个空stringbuilder; 碰到‘]’,将栈顶的stringbuilderappend到上一个stringbuilder中; 碰到普通字符时,将字符加入栈顶stringbuilder中。 如果从前往后遍历,则需要用一个栈把'['前的数字存在栈中;如果从后往前遍历,则不用。 */
public String decodeString(String s) {
// 申请存字符和倍数的栈
Stack<StringBuilder> strSK = new Stack<>();
Stack<Integer> intSK = new Stack<>();
// 初始化两个栈
strSK.push(new StringBuilder());
intSK.push(1);
// 遍历字符串
while (idx < s.length()) {
char ch = s.charAt(idx++);
// 如果ch是'[',则idx++(上面统一idx++了!),将新stringbuilder入栈。
if (ch == '[') {
strSK.push(new StringBuilder());
}
// 如果ch是']',则idx++,将栈顶stringbuilder以一定倍数融入上一个stringbuilder中。
else if (ch == ']') {
// 以一定倍数融合。
int size = intSK.pop();
StringBuilder topSB = strSK.pop();
StringBuilder peekSB = strSK.peek();
for (int i = 0; i < size; i++) peekSB.append(topSB.toString());
}
// 如果是普通字符,则加入topSB即可。
else if (Character.isLetter(ch)) strSK.peek().append(ch);
// 如果是数字,则需要获取该数有多大,并加入倍数栈中。
else {
int n = getNum(s, ch - '0');
intSK.push(n);
}
}
return strSK.peek().toString();
}
int idx = 0;// 遍历字符串的下标。
// 采用10倍扩容法来获取数字大小。
private int getNum(String s, int num) {
while (idx < s.length() && Character.isDigit(s.charAt(idx))) num = num * 10 + s.charAt(idx++) - '0';
return num;
}
}
2、栈模拟–从右到左
// 如果是倒序,就不用倍数栈了,每次拿到'['时,取后面的倍数即可,最后做一个翻转。
class DecodeString2 {
/* 括号匹配问题,可以递归,也可栈模拟。 */
// 栈模拟
/* 栈中存stringbuilder。 碰到‘[’时,入栈一个空stringbuilder; 碰到‘]’,将栈顶的stringbuilderappend到上一个stringbuilder中; 碰到普通字符时,将字符加入栈顶stringbuilder中。 如果从前往后遍历,则需要用一个栈把'['前的数字存在栈中;如果从后往前遍历,则不用。 */
public String decodeString(String s) {
// 初始化全局变量。
init(s);
// 申请存字符和倍数的栈
Stack<StringBuilder> strSK = new Stack<>();
// 初始化两个栈
strSK.push(new StringBuilder());
// 遍历字符串
while (idx >= 0) {
// 获取字符,统一idx--;
char ch = s.charAt(idx--);
// 如果ch是']',将新stringbuilder入栈。
if (ch == ']') strSK.push(new StringBuilder());
// 如果ch是']',则idx--,将栈顶stringbuilder以一定倍数融入上一个stringbuilder中。
if (ch == '[') {
// 以一定倍数融合。
int size = getNum();
StringBuilder topSB = strSK.pop();
StringBuilder peekSB = strSK.peek();
for (int i = 0; i < size; i++) peekSB.append(topSB.toString());
}
// 如果是普通字符,则加入topSB即可。
if (Character.isLetter(ch)) strSK.peek().append(ch);
}
return strSK.peek().reverse().toString();
}
// 初始化全局变量
private void init(String s) {
this.s = s;
this.idx = s.length() - 1;
}
String s;
int idx;// 遍历字符串的下标。
// 采用10倍扩容法来获取数字大小。
private int getNum() {
int num = 0;
int n = 1;
while (idx >= 0 && Character.isDigit(s.charAt(idx))) {
num += (s.charAt(idx--) - '0') * n;
n *= 10;
}
return num;
}
}
3、递归匹配
// 碰到'['则递归,并传入前面的参数。
class DecodeString3 {
/* 括号匹配问题,可以递归,也可栈模拟。 */
// 栈模拟
/* 栈中存stringbuilder。 碰到‘[’时,入栈一个空stringbuilder; 碰到‘]’,将栈顶的stringbuilderappend到上一个stringbuilder中; 碰到普通字符时,将字符加入栈顶stringbuilder中。 如果从前往后遍历,则需要用一个栈把'['前的数字存在栈中;如果从后往前遍历,则不用。 */
public String decodeString(String s) {
// 初始化全局变量。
init(s);
// 递归解决。
return dfs(1).toString();
}
public StringBuilder dfs(int size) {
StringBuilder sb = new StringBuilder();
int n = 1;
while (idx < s.length() && s.charAt(idx) != ']') {
char ch = s.charAt(idx++);
// 碰到'[',递归得到StringBuilder对象,并融入该层sb.
if (ch == '[') sb.append(dfs(n));
// 碰到数字,得到数字,更新n值。
if (Character.isDigit(ch)) n = getNum(ch - '0');
// 碰到普通字符,自己append加入。
if (Character.isLetter(ch)) sb.append(ch);
}
// 碰到']',或者访问完成了。
++idx;
// 字符放大,并返回。
StringBuilder rs = new StringBuilder();
for (int i = 0; i < size; i++) rs.append(sb.toString());
return rs;
}
// 初始化全局变量
private void init(String s) {
this.s = s;
}
String s;
int idx = 0;// 遍历字符串的下标。
// 采用10倍扩容法来获取数字大小。
private int getNum(int num) {
while (idx < s.length() && Character.isDigit(s.charAt(idx))) num = num * 10 + s.charAt(idx++) - '0';
return num;
}
}
总结
1)括号匹配问题,可递归匹配,也可栈模拟。对于栈模拟,需要知道栈里存储些什么。
2)一题多解,融合贯通,会发现不一样的bug,训练出严谨的逻辑,沉淀更多知识点。
参考文献
[1] LeetCode 字符串解码
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/13906.html