括号匹配问题的总结
括号匹配问题有若干种,这里分析其中一种括号里有数字有字符,然后求的最终结果的问题。
给出两道例题,Leetcode224和Leetcode394。
Leetcode224
题目描述
实现一个基本的计算器来计算一个简单的字符串表达式的值。
字符串表达式可以包含左括号 ( ,右括号 ),加号 + ,减号 -,非负整数和空格 。
示例
输入: "(1+(4+5+2)-3)+(6+8)"
输出: 23
解决方案
class Solution {
public int calculate(String s) {
int n = s.length();
Stack<Integer> st = new Stack<>();
int sign = 1,res = 0;
for(int i = 0;i < n;i++){
char c = s.charAt(i);
if(Character.isDigit(c)){
int t = c - '0';
while(i+1 < n && Character.isDigit(s.charAt(i+1))){
t = t*10 + s.charAt(++i) - '0';
}
res = sign * t + res;
}
else if(c == '-') sign = -1;
else if(c == '+') sign = 1;
//遇到左括号用栈保存之前的信息,并将信息重置
else if(c == '('){
st.add(res);
res = 0;
st.add(sign);
sign = 1;
}
//遇到右括号取出栈中信息,并计算出结果
else if(c == ')'){
res = st.pop()*res + st.pop();
}
}
return res;
}
}
Leetcode394
题目描述
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。
示例
s = "3[a]2[bc]", 返回 "aaabcbc".
s = "3[a2[c]]", 返回 "accaccacc".
s = "2[abc]3[cd]ef", 返回 "abcabccdcdcdef".
解决方案
class Solution {
public String decodeString(String s) {
int n = s.length();
StringBuilder res = new StringBuilder();
Stack<StringBuilder> stack = new Stack<>();
int t = 0;
for(int i = 0;i < n;i++){
char c = s.charAt(i);
if(Character.isDigit(c)){
t = c - '0';
while(i+1 < n && Character.isDigit(s.charAt(i+1))){
t = t*10 + s.charAt(++i)-'0';
}
}
//保存当前信息
else if(c == '['){
StringBuilder sb = new StringBuilder();
sb.append(t);
stack.add(sb);
t = 0;
stack.add(res);
res = new StringBuilder();
}
//提出信息,得到总结果
else if(c == ']'){
StringBuilder tmp = stack.pop();
int cnt = Integer.valueOf(stack.pop().toString());
for(int k = 0;k < cnt;k++) tmp.append(res);
res = tmp;
}
else{
res.append(c);
}
}
return res.toString();
}
}
总结:核心思路就是在遇到左括号,保存当前信息,然后去算括号中的逻辑,当遇到右括号时候,把之前栈中保存的之前的信息与括号里的信息进行拼接处理即可。