给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: 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".
- 思路1
分析题意,其实就是将[]内部的字符以前面的数字作为倍数展开,需要注意的是可能存在[]嵌套的情况。和括号匹配有点类似,利用栈来解决问题。
- 遍历字符串
s,如果s[i]!=']',入栈 - 如果
s[i]==']',此时需要我们依次出栈,找到[]内部需要展开的字符以及展开字符的倍数,将所得字符展开并且入栈。
示例:3[a2[c]]
1. 依次入栈 ---> 3[a2[c
2. 遇到']',出栈至'[',获得需要展开的字符c以及需要展开的倍数2
3. 将字符c展开并入栈 ---> 3[acc
4. 继续遍历,遇到第二个']'
5. 回到第2步,获得需要展开的字符acc以及倍数3
6. acc展开并入栈 ---> accaccacc
7. 遍历结束
char* decodeString(char * s){
if(s==NULL) return NULL;
int top = -1;
//使用char数组来模拟stack。
char *stack = (char *)malloc(5000);
char *tmp = (char *)malloc(2000);
for(int i = 0; s[i]; i++) {
if(s[i] != ']') {
stack[++top] = s[i];
}else {
//找到[]内部的字符
int tmpCount = 0;
while(stack[top] != '[') {
tmp[tmpCount++] = stack[top];
top--;
}
//弹出[
top--;
//寻找倍数k
int k = 0;
int multpy = 1;
//需要先判断top!=-1否则的话会出现数组越界的情况
while(top!=-1 && (stack[top] >= '0' && stack[top] <= '9') ) {
k += (stack[top]-'0')*multpy;
multpy *= 10;
top--;
}
//根据次数k将[]内部的字符入栈
while(k--) {
for(int start = tmpCount-1; start >= 0; start--) {
top++;
stack[top] = tmp[start];
}
}
}
}
stack[++top] = '\0';
free(tmp);
return stack;
}
- 思路2
其实每一次的展开都是一次重复的过程,可以使用递归来解决此问题
- 遇到
字符,放入结果res中 - 遇到
数字,计算倍数 - 遇到
[,对[内部进行递归 - 遇到
],递归结束,返回res以及标志位。 char **e的目的是为了告诉上一层递归函数遍历继续进行的位置。因为[]内部的字符已经计算完毕。
char* decodeString_inner(char * s, char **e) {
char *res = (char*)malloc(5000);
int idx = 0;
char *buff = NULL;
char *end = NULL;
int count = 0;
while(*s != '\0') {
if(isalpha(*s)) {
res[idx++] = *s;
}else if(isdigit(*s)) {
count = 10 * count + (*s - '0');
}else if(*s == '[') {
//对[]内部进行递归
buff = decodeString_inner(s+1, &end);
//将结果buff放入res中
while (count) {
strcpy(res+idx, buff);
idx += strlen(buff);
count--;
}
//改变s的位置,因为[]中都已经计算完毕
s = end;
}else if(*s == ']') {
//告诉上一层递归函数下一次遍历需要从]后面的字符开始
*e = s;
//因为res是一个很大的字符,因此需要增加结束位置
res[idx] = '\0';
return res;
}
s++;
}
res[idx] = '\0';
return res;
}
char* decodeString_1(char* s) {
char *end = "123";
return decodeString_inner(s, &end);
}