给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: n[encodedString],表示其中方括号内部的 encodedString 正好重复 n 次。注意 n 保证为正整数。
可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,可以认为原始数据不包含数字,所有的数字只表示重复的次数 n ,例如不会出现像 3a 或 2[4] 的输入。
示例 1:
输入:str = "3[a]2[bc]"
输出:"aaabcbc"
示例 2:
输入:str = "3[a2[c]]"
输出:"accaccacc"
示例 3:
输入:str = "2[abc]3[cd]ef"
输出:"abcabccdcdcdef"
示例 4:
输入:str = "abc3[cd]xyz"
输出:"abccdcdcdxyz"
package com.loo;
import java.util.Collections;
import java.util.LinkedList;
public class DecodeString {
public static int ptr = 0;
public static String src = null;
public static void main(String[] args) {
String s1 = "3[a]2[bc]";
String s2 = "3[a2[c]]";
String s3 = "2[abc]3[cd]ef";
String s4 = "abc3[cd]xyz";
System.out.println(decodeString(s1));
System.out.println(decodeString(s2));
System.out.println(decodeString(s3));
System.out.println(decodeString(s4));
System.out.println(decodeString2(s1));
System.out.println(decodeString2(s2));
System.out.println(decodeString2(s3));
System.out.println(decodeString2(s4));
}
// 栈操作
// 如果当前的字符为数位,解析出一个数字(连续的多个数位)并进栈
// 如果当前的字符为字母或者左括号,直接进栈
// 如果当前的字符为右括号,开始出栈,一直到左括号出栈,出栈序列反转后拼接成一个字符串,
// 此时取出栈顶的数字,就是这个字符串应该出现的次数,我们根据这个次数和字符串构造出新的字符串并进栈
// 重复如上操作,最终将栈中的元素按照从栈底到栈顶的顺序拼接起来,就得到了题目要求的解
public static String decodeString(String str) {
LinkedList<String> lk = new LinkedList<String>();
ptr = 0;
while (ptr < str.length()) {
char curr = str.charAt(ptr);
if (Character.isDigit(curr)) {
String digit = getDigits(str);
lk.addLast(digit);
} else if (Character.isLetter(curr) || curr == '[') {
lk.addLast(String.valueOf(str.charAt(ptr++)));
} else {
++ptr;
LinkedList<String> sub = new LinkedList<String>();
while (!"[".equals(lk.peekLast())) {
sub.addLast(lk.removeLast());
}
Collections.reverse(sub);
lk.removeLast();
int times = Integer.parseInt(lk.removeLast());
StringBuffer buff = new StringBuffer();
String result = getString(sub);
while (times-->0) {
buff.append(result);
}
lk.addLast(buff.toString());
}
}
return getString(lk);
}
public static String getDigits(String s) {
StringBuffer sb = new StringBuffer();
while (Character.isDigit(s.charAt(ptr))) {
sb.append(s.charAt(ptr++));
}
return sb.toString();
}
public static String getString(LinkedList<String> lk) {
StringBuffer sb = new StringBuffer();
for (String s : lk) {
sb.append(s);
}
return sb.toString();
}
// 递归
public static String decodeString2(String str) {
src = str;
ptr = 0;
return getString2();
}
public static String getString2() {
if (ptr == src.length() || src.charAt(ptr) == ']') {
return "";
}
char curr = src.charAt(ptr);
int times = 1;
String result = "";
if (Character.isDigit(curr)) {
times = getDigits2();
ptr++;
String str = getString2();
ptr++;
while (times-->0) {
result += str;
}
} else if (Character.isLetter(curr)) {
result = String.valueOf(src.charAt(ptr++));
}
return result + getString2();
}
public static int getDigits2() {
int ret = 0;
while (ptr<src.length() && Character.isDigit(src.charAt(ptr))) {
ret = ret * 10 + src.charAt(ptr++) - '0';
}
return ret;
}
}