数据结构与算法:字符串编码

给定一个经过编码的字符串,返回它解码后的字符串。

编码规则为: 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".

解题思路:

例如:12[a]为例;

1.遍历字符串 S

2.如果当前字符不为方括号"]" 则入栈stack中;

2.如果当前字符遇到了方括号"]" 则:

① 首先找到要复制的字符,例如stack="12[a",那么我要首先获取字符a;将这个a保存在另外一个栈去tempStack;

② 接下来,要找到需要备份的数量,例如stack="12[a",因为出栈过字符"a",则当前的top指向了"[",也就是等于2;

③ 而12对于字符串是2个字符, 我们要通过遍历找到数字12的top上限/下限的位置索引, 此时上限curTop = 2, 下限通过出栈,top = -1;

④ 根据范围[-1,2],读取出12保存到strOfInt 字符串中来, 并且将字符"12\0",转化成数字12;

⑤ 当前top=-1,将tempStack中的字符a,复制12份入栈到stack中来;

⑥ 为当前的stack扩容, 在stack字符的末尾添加字符结束符合'\0';

代码实现:

char * decodeString(char * s) {
    /*.
     1.获取字符串长度
     2.设置默认栈长度50
     3.开辟字符串栈(空间为50)
     4.设置栈头指针top = -1;
     */
    int len = (int)strlen(s);
    int stackSize = 50;
    char* stack = (char*)malloc(stackSize * sizeof(char));
    int top = -1;    
    //遍历字符串,在没有遇到"]" 之前全部入栈
    for (int i = 0; i < len; ++i) {
        if (s[i] != ']') {
            //优化:如果top到达了栈的上限,则为栈扩容;
            if (top == stackSize - 1) {
                stack = realloc(stack, (stackSize += 50) * sizeof(char));
            }
            //将字符入栈stack
            stack[++top] = s[i];
            printf("#① 没有遇到']'之前# top = %d\n",top);
        }
        else {
            int tempSize = 10;
            char* temp = (char*)malloc(tempSize * sizeof(char));
            int topOfTemp = -1;
            printf("#② 开始获取要复制的字符信息之前 # top = %d\n",top);
            //从栈顶位置开始遍历stack,直到"["结束;
            //把[a]这个字母a 赋值到temp栈中来;
            //简单说,就是将stack中方括号里的字符出栈,复制到temp栈中来;
            while (stack[top] != '[') {
                //优化:如果topOfTemp到达了栈的上限,则为栈扩容;
                if (topOfTemp == tempSize - 1) {
                    temp = realloc(temp, (tempSize += 10) * sizeof(char));
                }
                //temp栈的栈顶指针自增;
                ++topOfTemp;
                //将stack栈顶字符复制到temp栈中来;
                temp[topOfTemp] = stack[top];
                //stack出栈,则top栈顶指针递减;
                top--;
            }
            printf("#② 开始获取要复制的字符信息之后 # top = %d\n",top);
            //找到倍数数字.strOfInt字符串;
            //注意:如果是大于1位的情况就处理
            char strOfInt[11];
            //p记录当前的top;
            int curTop = top;
            printf("#③ 开始获取数字,数字位置上限 # curTop = %d\n",curTop);
            //top--的目的是把"["剔除,才能找到数字;
            top--;
            //遍历stack得出数字
            //例如39[a] 就要找到这个数字39.
            //p指向当前的top,我就知道上限了; 那么接下来通过循环来找它的数字下限;
            //结束条件:栈指针指向为空! stack[top] 不等于数字
            while (top != -1 && stack[top] >= '0' && stack[top] <= '9') {
                top--;
            }
            printf("#③ 开始获取数字,数字位置下限 # top = %d\n",top);           
            //从top-1遍历到p之间, 把stack[top-1,p]之间的数字复制到strOfInt中来;
            //39中3和9都是字符. 我们要获取到这2个数字,存储到strOfInt数组
            for (int j = top + 1; j < curTop; ++j) {
                strOfInt[j - (top + 1)] = stack[j];
            }
            //为字符串strOfInt数组加一个字符结束后缀'\0'
            strOfInt[curTop - (top + 1)] = '\0';
            //把strOfInt字符串转换成整数 atoi函数;
            //把字母复制strOfInt份到stack中去;
            //例如39[a],就需要把复制39份a进去;
            int curNum = atoi(strOfInt);
            for (int k = 0; k < curNum ; ++k) {
                //从-1到topOfTemp 范围内,复制curNum份到stackTop中去;
                int kk = topOfTemp;
                while (kk != -1) {                 
                    //优化:如果stack到达了栈的上限,则为栈扩容;
                    if (top == stackSize - 1) {
                        stack = realloc(stack, (stackSize += 50) * sizeof(char));
                    }
                    //将temp栈的字符复制到stack中;
                    //stack[++top] = temp[kk--];
                    ++top;
                    stack[top] = temp[kk];
                    kk--;
                }
            }
            free(temp);
            temp = NULL;
        }
    }
    //realloc 动态内存调整;
    //void *realloc(void *mem_address, unsigned int newsize);
    //构成字符串stack后, 在stack的空间扩容.
    char* ans = realloc(stack, (top + 1) * sizeof(char));
    ans[++top] = '\0';
    //stack 栈不用,则释放;
    free(stack);
    return ans;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辣椒种子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值