给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: k[encoded_string]
,表示其中方括号内部的 encoded_string
正好重复 k
次。注意 k
保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k
,例如不会出现像 3a
或 2[4]
的输入。
示例 1:
输入:s = "3[a]2[bc]"
输出:"aaabcbc"
示例 2:
输入:s = "3[a2[c]]"
输出:"accaccacc"
示例 3:
输入:s = "2[abc]3[cd]ef"
输出:"abcabccdcdcdef"
示例 4:
输入:s = "abc3[cd]xyz"
输出:"abccdcdcdxyz"
public string DecodeString(string s) {
// 存储重复次数的栈,用于处理嵌套的数字(如"3[a2[c]]"中的3和2)
Stack<int> numStack = new Stack<int>();
// 存储字符串片段的栈,用于保存括号前的字符串(如"3[a"中的空字符串)
Stack<string> strStack = new Stack<string>();
string currentStr = ""; // 当前正在构建的字符串
int currentNum = 0; // 当前解析的数字(处理多位数,如"123")
foreach (char c in s) {
if (char.IsDigit(c)) {
// 处理数字字符:将字符转换为整数并累加到currentNum
// 例如 "123" -> 1 → 1*10+2=12 → 12*10+3=123
currentNum = currentNum * 10 + (c - '0');
} else if (c == '[') {
// 遇到左括号:将当前字符串和数字压入栈
// 压栈后重置currentStr和currentNum,准备处理括号内的内容
strStack.Push(currentStr);
numStack.Push(currentNum);
currentStr = ""; // 重置currentStr以捕获括号内的新字符串
currentNum = 0; // 重置currentNum以捕获括号内可能的新数字
} else if (c == ']') {
// 遇到右括号:弹出栈顶数字(重复次数)和字符串(括号前的字符串)
int repeatTimes = numStack.Pop(); // 获取重复次数,如栈顶的2
string prevStr = strStack.Pop(); // 获取括号前的字符串,如栈顶的"a"
// 将当前字符串重复repeatTimes次,并与prevStr拼接
// 例如:prevStr="a", currentStr="c" → 重复2次得到"cc" → 拼接成"acc"
currentStr = prevStr + string.Concat(Enumerable.Repeat(currentStr, repeatTimes));
} else {
// 普通字符(如字母):直接拼接到当前字符串
currentStr += c;
}
}
// 返回最终解码后的字符串(所有括号已处理完毕)
return currentStr;
}