字符串编码(LeetCode-中等)
给定一个经过编码的字符串,返回它解码后的字符串。编码规则为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"
思路:
- 循环遍历字符串
- 遇到不是']'字符,依次将字符入栈
- 遇到']'字符,开始出栈 3.1 出栈会遇到字母、数字和'['字符。遇到字母,整理成字符串。遇到数字,进行数字转换。 3.2、此时栈为空,说明没有嵌套关系。例如:3[a]2[bc]中的3a部分。栈不为空,有嵌套关系。例如"3[a2[c]]的2c部分。嵌套关系内部解决后获取到的字符,再次入栈。
- 解析后吧字符串添加到返回的字符串变量中。
- 最后栈不是空栈,说明后面有不需要解码的字符。例如:2[abc]3[cd]ef中的ef。直接插入到返回字符串尾部就可以了。
代码
#define Char2Int(x) (x-'0')
void decodeString(char *encoded, char *decode) {
SqStack stack;
initStack(&stack);
char *p = encoded;
//遍历字符串
while (*p != '\0') {
//如果遇到']',处理之前的字符串
if (*p == ']') {
int multi = 1;//用于计算多位数字,multi * 10,例如12[b]:获取到2时,mutil = 1;获取到1时,mutil = 10。
int count = 0;
SElemType chr = (SElemType)malloc(sizeof(char) * 100);
*chr = '\0';
//对栈循环
while (!isEmptyStack(stack)) {
//获取栈顶元素
char *topElem;
getTopElem(stack, &topElem);
//如果是字母
if (*topElem >= 'a' && *topElem <= 'z') {
//如果倍数为初始值,说明出栈过程中还没有遇到过数字,整理字符串
if (multi == 1) {
SElemType popElem;
popElemFromStack(&stack, &popElem);
//
SElemType tmp = (SElemType)malloc(sizeof(char) * 100);
*tmp = '\0';
strcpy(tmp, popElem);
chr = strcat(tmp, chr);
} else {//嵌套模式下,会有先遇到数字,然后遇到字母的情况,上一个出栈元素是数字,退出当前栈循环
break;
}
} else if (*topElem == '[') {//如果遇到'[',初始数字的位数的倍数
char *popElem;
popElemFromStack(&stack, &popElem);
multi = 1;
} else if (*topElem >= '0' && *topElem <= '9') {//如果是数字,计算出count
char *popElem;
popElemFromStack(&stack, &popElem);
count = multi * Char2Int(*popElem) + count;
multi *= 10;
}
}
//此时栈不为空,说明有嵌套逻辑,当前的内部嵌套已经执行完成。把当前的结构再入栈
if (!isEmptyStack(stack)) {
for (int i = 0; i < count; i ++) {
pushElem2Stack(&stack, chr);
}
} else {
//栈已经为空,把当前的字符串赋值给返回值
for (int i = 0; i < count; i ++) {
strcat(decode, chr);
}
}
free(chr);
} else {
//其他字符 一次入栈 会入栈的有数字、字母、'['
char *chr = (char*)malloc(sizeof(char) * 100);
*chr = '\0';
strncat(chr, p, 1);
pushElem2Stack(&stack, chr);
}
p ++;
}
SElemType tmp = (SElemType)malloc(sizeof(char) * 100);
*tmp = '\0';
//此时栈不为空,说明后面没有需要解码的字符,直接追加的要返回字符串的后面
while (!isEmptyStack(stack)) {
SElemType popElem;
popElemFromStack(&stack, &popElem);
tmp = strcat(popElem, tmp);
}
strcat(decode, tmp);
}
int main(int argc, const char * argv[]) {
// insert code here...
printf("Hello, World!\n");
char *decode = (char*)malloc(sizeof(char) * 100);
// decodeString("3[a]2[bc]", decode);
// decodeString("3[a2[c]]", decode);
decodeString("2[abc]3[cd]ef", decode);
printf("%s\n", decode);
return 0;
}
运行
