算法题-字符串编码

字符串编码(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"算法

思路:

  1. 循环遍历字符串
  2. 遇到不是']'字符,依次将字符入栈
  3. 遇到']'字符,开始出栈 3.1 出栈会遇到字母、数字和'['字符。遇到字母,整理成字符串。遇到数字,进行数字转换。 3.二、此时栈为空,说明没有嵌套关系。例如:3[a]2[bc]中的3a部分。栈不为空,有嵌套关系。例如"3[a2[c]]的2c部分。嵌套关系内部解决后获取到的字符,再次入栈。
  4. 解析后吧字符串添加到返回的字符串变量中。
  5. 最后栈不是空栈,说明后面有不须要解码的字符。例如: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;
}
复制代码

运行

传送门

算法题-去除重复字母markdown

相关文章
相关标签/搜索