The encoding rule is: k[encoded_string]
, where the encoded_string inside the square brackets is being repeated exactlyk times. Note that k is guaranteed to be a positive integer.
You may assume that the input string is always valid; No extra white spaces, square brackets are well-formed, etc.
Furthermore, you may assume that the original data does not contain any digits and that digits are only for those repeat numbers,k. For example, there won't be input like 3a
or 2[4]
.
Examples:
s = "3[a]2[bc]", return "aaabcbc". s = "3[a2[c]]", return "accaccacc". s = "2[abc]3[cd]ef", return "abcabccdcdcdef".
题目的大意是给定一个字符串,字符串当中包含了一些数字k,要将数字后面的中括号内的内容重复k次,得到一个新的字符串。
字符串的内容可能会出现多重嵌套,所以直接解决这个问题会比较困难。如果只是考虑一层嵌套的话问题会变得比较简单,所以我们可以尝试用递归函数来解决这个问题。
具体的方法就是用一个递归函数decode(),当检测到当前的字符是数字时,就先确定数字的大小,然后确定该数字后面的那个中括号包含的范围,然后以中括号包含的范围为一个子串,然后以这个子串为目标串递归调用decode函数,调用的次数由刚刚确定的数字的大小决定。
需要注意的是字符中的数字并不是一定只有1位,所以要由函数exchange来将字符串转为整数。
确定中括号的范围需要用到与解决括号匹配问题类似的算法,利用栈来确定中括号的完整范围。另外比较容易出错的地方就是数组的下标,因为需要多次地递归调用函数,所以下标的值一定要非常清楚。
这个程序最起码需要将目标字符串扫一遍,后面的递归调用则与字符串中的数字有关。如果目标串的大小为N,最后结果字符串的大小为L,那么这个算法的复杂度是O(L+N)
以下为源程序:
class Solution {
public:
string decodeString(string s) {
string r;
decode(s,r);
return r;
}
int exchange(string s,int& i)
{
int num=0;
while(s[i]>='0'&&s[i]<='9')
{
num*=10;
num+=s[i]-'0';
i++;
}
return num;
}
void decode(string s,string& r)
{
for(int i=0;i<s.size();i++)
{
if(s[i]>='0'&&s[i]<='9')
{
int num=exchange(s,i);
stack<char> st;
st.push(s[i]);
i++;
string t;
while(!st.empty())
{
if(s[i]==']') st.pop();
else if(s[i]=='[') st.push(s[i]);
t+=s[i];
i++;
}
i--;
for(int j=0;j<num;j++) decode(t,r);
}
else if(s[i]==']') return;
else r+=s[i];
}
}
};