华为OD机试 - 压缩报文还原 - 栈(Python/JS/C/C++ 2023 B卷 100分)

在这里插入图片描述

华为OD机试 2024E卷题库疯狂收录中,刷题点这里

专栏导读

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。

一、题目描述

为了提高数据传输的效率,会对传输的报文进行压缩处理。

输入一个压缩后的报文,请返回它解压后的原始报文。

压缩规则:n[str],表示方括号内部的str正好重复n次。

注意:

  1. n为正整数,取值范围0~100,str只包含小写英文字母,不考虑异常情况。
  2. 原始报文长度不会超过1000,不考虑异常的情况。

二、输入描述

输入压缩后的报文:

  1. 不考虑无效的输入,报文没有额外的空格,方括号总是符合格式的要求;
  2. 原始报文不包含数字,所有的数字只表示重复的次数n,例如不会出现像5b或3[8]的输入;

三、输出描述

解压后的原始报文。

四、测试用例

测试用例1:

1、输入

2[abc]3[cd]ef

2、输出

abcabccdcdcdef

3、说明

2[abc]解压为abcabc,3[cd]解压为cdcdcd,最终加上ef得到abcabccdcdcdef。

测试用例2:

1、输入

10[a]

2、输出

aaaaaaaaaa

3、说明

10[a]解压为a重复10次。

五、解题思路

  1. 迭代遍历字符串:逐字符处理输入字符串。
  2. 数字处理:遇到数字时,计算当前的重复次数k。
  3. '[‘处理:遇到’['时,将当前的k和当前字符串current压入对应的栈中,然后重置current和k。
  4. ']‘处理:遇到’]'时,弹出最近的重复次数count和之前的字符串decoded,将当前字符串current重复count次后,拼接回decoded。
  5. 字符处理:遇到字母时,直接追加到当前字符串current中。
  6. 最终结果:遍历完成后,current即为解压后的原始报文。

为什么采用栈:

栈能够有效地处理嵌套的结构,通过后进先出的特性,确保内层的解压先于外层的解压,从而正确地构建最终的解压字符串。

六、Python算法源码

def decompress(s):
    count_stack = []
    string_stack = []
    current = []
    k = 0

    for ch in s:
        if ch.isdigit():
            k = k * 10 + int(ch)  # 计算重复次数
        elif ch == '[':
            count_stack.append(k)  # 压入重复次数
            string_stack.append(current)  # 压入当前字符串
            current = []  # 重置当前字符串
            k = 0  # 重置重复次数
        elif ch == ']':
            count = count_stack.pop()  # 弹出重复次数
            decoded = string_stack.pop()  # 弹出之前的字符串
            current = decoded + current * count  # 拼接解压后的字符串
        else:
            current.append(ch)  # 追加当前字符

    return ''.join(current)

if __name__ == "__main__":
    input_str = input()
    print(decompress(input_str))

七、JavaScript算法源码

function decompress(s) {
    let countStack = [];
    let stringStack = [];
    let current = '';
    let k = 0;

    for(let ch of s){
        if(!isNaN(ch)){
            k = k * 10 + parseInt(ch); // 计算重复次数
        }
        else if(ch === '['){
            countStack.push(k); // 压入重复次数
            stringStack.push(current); // 压入当前字符串
            current = ''; // 重置当前字符串
            k = 0; // 重置重复次数
        }
        else if(ch === ']'){
            let count = countStack.pop(); // 弹出重复次数
            let decoded = stringStack.pop(); // 弹出之前的字符串
            current = decoded + current.repeat(count); // 拼接解压后的字符串
        }
        else{
            current += ch; // 追加当前字符
        }
    }

    return current;
}

// 读取输入并输出结果
const readline = require('readline');
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});
rl.on('line', (input) => {
    console.log(decompress(input));
    rl.close();
});

八、C算法源码

#include 
#include 
#include 
#include 

#define MAX 1000

typedef struct {
    int data[MAX];
    int top;
} IntStack;

typedef struct {
    char data[MAX];
    int top;
} CharStack;

// 初始化整数栈
void initIntStack(IntStack *s) {
    s->top = -1;
}

// 压入整数
void pushInt(IntStack *s, int val) {
    if(s->top < MAX -1){
        s->data[++(s->top)] = val;
    }
}

// 弹出整数
int popInt(IntStack *s){
    if(s->top >=0){
        return s->data[(s->top)--];
    }
    return -1;
}

// 初始化字符栈
void initCharStack(CharStack *s){
    s->top = -1;
}

// 压入字符
void pushChar(CharStack *s, char ch){
    if(s->top < MAX -1){
        s->data[++(s->top)] = ch;
    }
}

// 弹出字符
char popChar(CharStack *s){
    if(s->top >=0){
        return s->data[(s->top)--];
    }
    return '\0';
}

int main(){
    char s[MAX];
    scanf("%s", s);
    int len = strlen(s);
    IntStack countStack;
    CharStack stringStack;
    initIntStack(&countStack);
    initCharStack(&stringStack);
    char current[MAX] = "";
    int k = 0;

    for(int i =0;i<len;i++){
        char ch = s[i];
        if(isdigit(ch)){
            k = k *10 + (ch - '0'); // 计算重复次数
        }
        else if(ch == '['){
            pushInt(&countStack, k); // 压入重复次数
            strcpy(stringStack.data, current);
            pushChar(&stringStack, '\0'); // 标记字符串结束
            current[0] = '\0'; // 重置当前字符串
            k =0; // 重置重复次数
        }
        else if(ch == ']'){
            int count = popInt(&countStack); // 弹出重复次数
            // 弹出之前的字符串
            char prev[MAX];
            int idx =0;
            while((prev[idx] = popChar(&stringStack)) != '\0'){
                idx++;
            }
            prev[idx] = '\0';
            // 重复当前字符串
            char temp[MAX] = "";
            for(int j=0;j<count;j++){
                strcat(temp, current);
            }
            // 拼接
            strcat(prev, temp);
            strcpy(current, prev);
        }
        else{
            int len_cur = strlen(current);
            current[len_cur] = ch;
            current[len_cur+1] = '\0'; // 追加当前字符
        }
    }

    printf("%s", current);
    return 0;
}

九、C++算法源码

#include 
using namespace std;

int decompress(string s){
    stack<int> countStack; // 存储重复次数的栈
    stack<string> stringStack; // 存储字符串的栈
    string current = "";
    int k = 0;

    for(char ch : s){
        if(isdigit(ch)){
            k = k * 10 + (ch - '0'); // 计算重复次数
        }
        else if(ch == '['){
            countStack.push(k); // 压入重复次数
            stringStack.push(current); // 压入当前字符串
            current = ""; // 重置当前字符串
            k = 0; // 重置重复次数
        }
        else if(ch == ']'){
            int count = countStack.top(); countStack.pop(); // 弹出重复次数
            string decoded = stringStack.top(); stringStack.pop(); // 弹出之前的字符串
            decoded += string(current.begin(), current.end()) ;
            string temp = "";
            for(int i=0;i<count;i++) temp += current; // 重复当前字符串
            current = decoded + temp; // 拼接解压后的字符串
        }
        else{
            current += ch; // 追加当前字符
        }
    }

    return current;
}

int main(){
    string s;
    cin >> s;
    cout << decompress(s);
    return 0;
}


下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)

本文收录于,华为OD机试真题(Python/JS/C/C++)

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。

在这里插入图片描述

你可能感兴趣的:(搬砖工逆袭Java架构师,华为od,python,javascript)