题目描述:
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: 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"
解析:采用堆栈的方式,开辟一个数字栈numstack,一个待选字符栈standstack,一个结果栈resstack,然后一次读取输入字符串,遇到数字就将数字解析之后压入数字栈,遇到左括号和字符,就压入结果栈,遇到右括号,就将结果栈里的字符依次从后往前弹出到待选字符栈,直到弹出左括号,然后再取数字栈栈顶元素作为重复次数,将待选字符栈里的字符进行填充(此时是倒序填充),填充完毕依次将待选字符栈里的字符弹出到结果栈中(此时弹出结束,顺序恢复为正序)
执行用时:0 ms, 在所有 C 提交中击败了100.00%的用户
内存消耗:6.6 MB, 在所有 C 提交中击败了34.32%的用户
char * decodeString(char * s){
int len = strlen(s);
char*stack = (char*)malloc(sizeof(char)*10000);//中间栈
char* ret = (char*)malloc(sizeof(char)*10000);//返回值
memset(stack,0,sizeof(char)*10000);
memset(ret,0,sizeof(char)*10000);
int front=0,bootm=0,ret_i=0;
while(bootm<len){
if(s[bootm]==']'){//若检测到右括号
memset(stack,0,sizeof(char)*10000);
front=ret_i;
while(ret[front]!='[')front--;//遍历返回栈寻找左括号
int mlen = ret_i - front -1;//计算左右括号内的长度
int num_i = front-1;//定位重复次数
while(num_i>=0&&ret[num_i]<='9'&&ret[num_i]>='0')num_i--;//要考虑超过10的次数
char num[10] = {0};
memcpy(num,&ret[num_i+1],sizeof(char)*(front-1-num_i));//将数字字符转换成数字
int time = atoi(num);
while(time--)memcpy(&stack[time*mlen],&ret[front+1],mlen*sizeof(char));//stack存储重复的字符串部分
memcpy(&ret[num_i+1],stack,strlen(stack)*sizeof(char));//将重复部分重新写入返回栈
ret_i = num_i+1+strlen(stack);//定位返回栈的大小
ret[ret_i] = 0;//及时给末尾加0
bootm++;
}else{//若未检测到右括号
ret[ret_i++] = s[bootm++];//将s中的值放入返回栈中
}
}
return ret;
}