算法題-字符串編碼

字符串編碼(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

相關文章
相關標籤/搜索