力扣面试题(十)

1、字符串解码

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

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

 思路:采用入栈的思想,如果不是']'这个字符进行入栈,是‘]’开始出栈,出栈到‘[’,左括号旁边就是复制的次数,根据复制的次数进行赋值。

char* decodeString(char* s) {
    char * str = malloc(256*sizeof(char));
    int count = 256;
    int len = strlen(s);
    char * tmp = 0;
    int j = 0, k = 0, num = 0;
    int pre = 0;
    int digit_10 = 1;
    int copy_len = 0;

    for(int i = 0; i < len; i++){
        if(s[i] != ']'){
            if(j+1 < count){
                 str[j++] = s[i];                
            }
            else{
                count += 256;
                if(!(str = realloc(str, count*sizeof(char)))){
                    return str;
                }
                str[j++] = s[i];
            }             
        }
        else{
            k = j;                       
            while(str[j] != '['){
                j--;
            }
            /*为了防止遍历处理[时遇到问题,将其置成空格*/
            str[j] = ' ';
            pre = j;

            copy_len = k - pre-1;
            
            /*将字符转换成十进制数*/
            while(j-1 >=0 &&  isdigit(str[--j])){
                num += (str[j] - '0') * digit_10;     
                digit_10 *=  10;                
            }
            
            if(j!= 0)
                j++;

            /*申请临时内存 ,目的是将str中出栈的数据保存,因为在赋值的过程中存在覆盖的情况*/                       
            tmp = malloc((copy_len+1)*sizeof(char));
            memset(tmp, 0, copy_len+1);

            for(int p = 0; p < copy_len; p++){
                tmp[p] = str[pre+1+p];
            }

            for(int n = 0 ; n < num; n++){
                if(j + copy_len  >= count){
                    count += 256;
                    /*realloc之后一定要将指针赋值给str,因为会存在内存移动的情况*/
                    if(!(str = realloc(str, count*sizeof(char)))){
                        return str;
                    }                    
                }
                
                for(int p = 0; p < copy_len; p++){
                    str[j+p] = tmp[p];
                }                            
                j += copy_len;                         
            }

            free(tmp); 
            digit_10 = 1;
            num = 0;


        }
    }

    str[j] = '\0';
    return str;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值