华为OD机试 - 模拟数据序列化传输(Python/JS/C/C++ 2025 B卷 200分)

在这里插入图片描述

2025B卷华为OD机试统一考试题库清单(持续收录中)以及考点说明(Python/JS/C/C++)

专栏导读

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

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

一、题目描述

模拟一套简化的序列化传输方式,请实现下面的数据编码与解码过程。

编码前数据格式为[位置,类型,值],多个数据的时侯用逗号隔开,位置仅支持数字,不考虑重复场景;类型仅支持: Integer / String / Compose(Compose的数据类型表示该存储的数据也需要编码)。

编码后数据参考图示,数据区的格式是: 位置#类型#长度#数据,类型存储需要编码,Integer->0;String->1;Compose->2,长度是指数据的字符长度;数据仅允许数字、大写字母、小写字母、空格。

输入的编码字符长度不能超过1000,一个数据的格式错误,则解码剩余数据,其他错误输出ENCODE_ERROR。

输入的解码字符不能超过1000,数据区异常则跳过,继续解析剩余数据区,其余异常输出DECODE_ERROR。

二、输入描述

输入有行:

第一行是命令,1表示编码,2表示解码,第二行为输入待解码、解码的字符,数据最多嵌套10层,[1,Compose,[1,String,Second]] 为2层嵌套。

三、输出描述

如果输入要求是编码,则输出编码结果;如果输入要求是解码,则输出解码结果;当异常时输出对应的错误字符。

四、测试用例

测试用例1:

1、输入

1
[1,String,I am Mary],[2,Integer,23],[3,Long,100000],[4,Compose,[1,String,I am Kitty],[2,Integer,44]]

2、输出

1#19#I am Mary2#0#2#234#2#25#1#1#10#I am Kitty2#0#2#44

3、说明

由于Long型未不支持类型,所以数据[3,Long,100000]自动被过滤掉。

测试用例2:

1、输入

2
1#1#9#I am Mary2#0#2#233#0#3#8794#2#25#1#1#10#I am Kitty2#0#2#44

2、输出

[1,String,I am Mary],[2,Integer,23],[3,Integer,879],[4,Compose,[1,String,I am Kitty],[2,Integer,44]]

五、解题思路

  1. 使用括号匹配技术解析每个[位置,类型,值]数据项
  2. 类型映射:Integer→0, String→1, Compose→2
  3. 按格式位置#类型编码#数据长度#数据生成编码
  4. 对Compose类型递归编码内部数据

使用层级计数器准确找到完整数据项边界。

六、Python算法源码

import re
import sys

def main():
    """主函数:处理输入并调用相应的编码或解码函数"""
    # 读取命令:1表示编码,2表示解码
    command = int(input())
    # 读取待处理的数据
    data = input()
    
    if command == 1:
        # 执行编码操作
        print(encode(data))
    elif command == 2:
        # 执行解码操作
        print(decode(data))

def encode(input_str):
    """
    编码函数:将输入的数据格式转换为编码格式
    参数:input_str - 输入字符串,格式为[位置,类型,值],...
    返回:编码后的字符串
    """
    try:
        # 检查输入长度限制
        if len(input_str) > 1000:
            return "ENCODE_ERROR"
        
        result = []
        data_items = parse_data_items(input_str)
        
        # 处理每个数据项
        for item in data_items:
            encoded = encode_item(item)
            if encoded != "ENCODE_ERROR":
                result.append(encoded)
        
        return ''.join(result)
    except Exception:
        return "ENCODE_ERROR"

def decode(input_str):
    """
    解码函数:将编码格式转换为原始数据格式
    参数:input_str - 编码后的字符串
    返回:解码后的字符串
    """
    try:
        # 检查输入长度限制
        if len(input_str) > 1000:
            return "DECODE_ERROR"
        
        decoded_items = []
        index = 0
        
        # 逐个解析编码数据
        while index < len(input_str):
            try:
                decoded_data = decode_item(input_str, index)
                if decoded_data:
                    decoded_items.append(decoded_data['decoded_string'])
                    index = decoded_data['next_index']
                else:
                    break
            except Exception:
                # 数据区异常则跳过,寻找下一个可能的数据开始位置
                index += 1
        
        return ','.join(decoded_items)
    except Exception:
        return "DECODE_ERROR"

def parse_data_items(input_str):
    """
    解析输入字符串中的数据项列表
    参数:input_str - 输入字符串
    返回:数据项列表
    """
    items = []
    level = 0
    start = 0
    
    for i, c in enumerate(input_str):
        if c == '[':
            level += 1
        elif c == ']':
            level -= 1
            if level == 0:
                # 找到一个完整的数据项
                items.append(input_str[start:i+1])
                # 跳过可能的逗号
                if i + 1 < len(input_str) and input_str[i + 1] == ',':
                    i += 1
                start = i + 1
    
    return items

def encode_item(item):
    """
    编码单个数据项
    参数:item - 数据项字符串,格式为[位置,类型,值]
    返回:编码后的字符串
    """
    try:
        # 去掉首尾的方括号
        content = item[1:-1]
        
        # 解析位置、类型、值
        parsed = parse_item(content)
        if not parsed:
            return "ENCODE_ERROR"
        
        # 获取类型编码
        type_code = get_type_code(parsed['type'])
        if type_code == -1:
            return "ENCODE_ERROR"  # 不支持的类型
        
        if parsed['type'] == "Compose":
            # Compose类型需要递归编码内部数据
            data = encode(parsed['value'])
            if data == "ENCODE_ERROR":
                return "ENCODE_ERROR"
        else:
            data = parsed['value']
        
        # 验证数据格式:只允许数字、大写字母、小写字母、空格
        if not is_valid_data(data) and parsed['type'] != "Compose":
            return "ENCODE_ERROR"
        
        # 构建编码结果:位置#类型#长度#数据
        return f"{parsed['position']}#{type_code}#{len(data)}#{data}"
        
    except Exception:
        return "ENCODE_ERROR"

def parse_item(content):
    """
    解析数据项内容
    参数:content - 数据项内容(不含方括号)
    返回:解析后的数据字典
    """
    try:
        # 找到第一个逗号,分离位置
        first_comma = content.find(',')
        if first_comma == -1:
            return None
        
        position = content[:first_comma]
        
        # 对于不同类型,需要特殊处理,因为值中可能包含逗号
        type_start = first_comma + 1
        type_end = -1
        
        # 查找类型结束位置
        if content.startswith("Compose", type_start):
            type_end = type_start + 7  # len("Compose")
        elif content.startswith("String", type_start):
            type_end = type_start + 6  # len("String")
        elif content.startswith("Integer", type_start):
            type_end = type_start + 7  # len("Integer")
        
        if type_end == -1 or type_end >= len(content) or content[type_end] != ',':
            return None
        
        type_name = content[type_start:type_end]
        value = content[type_end + 1:]
        
        return {'position': position, 'type': type_name, 'value': value}
    except Exception:
        return None

def get_type_code(type_name):
    """
    获取类型对应的编码
    参数:type_name - 类型名称
    返回:类型编码,-1表示不支持的类型
    """
    type_codes = {
        "Integer": 0,
        "String": 1,
        "Compose": 2
    }
    return type_codes.get(type_name, -1)

def get_type_name(code):
    """
    获取编码对应的类型名称
    参数:code - 类型编码
    返回:类型名称
    """
    type_names = {
        0: "Integer",
        1: "String",
        2: "Compose"
    }
    return type_names.get(code)

def is_valid_data(data):
    """
    验证数据是否有效(只包含数字、大写字母、小写字母、空格)
    参数:data - 待验证的数据
    返回:是否有效
    """
    for c in data:
        if not (c.isalnum() or c == ' '):
            return False
    return True

def decode_item(input_str, start_index):
    """
    解码单个数据项
    参数:input_str - 编码字符串
           start_index - 开始位置
    返回:解码结果字典,包含解码字符串和下一个位置
    """
    try:
        index = start_index
        
        # 解析位置
        first_sharp = input_str.find('#', index)
        if first_sharp == -1:
            return None
        position = input_str[index:first_sharp]
        
        # 解析类型编码
        index = first_sharp + 1
        second_sharp = input_str.find('#', index)
        if second_sharp == -1:
            return None
        type_code = int(input_str[index:second_sharp])
        type_name = get_type_name(type_code)
        if not type_name:
            return None
        
        # 解析长度
        index = second_sharp + 1
        third_sharp = input_str.find('#', index)
        if third_sharp == -1:
            return None
        length = int(input_str[index:third_sharp])
        
        # 解析数据
        index = third_sharp + 1
        if index + length > len(input_str):
            return None
        data = input_str[index:index + length]
        
        if type_name == "Compose":
            # Compose类型需要递归解码
            inner_decoded = decode(data)
            if inner_decoded == "DECODE_ERROR":
                return None
            decoded_string = f"[{position},{type_name},{inner_decoded}]"
        else:
            decoded_string = f"[{position},{type_name},{data}]"
        
        return {
            'decoded_string': decoded_string,
            'next_index': index + length
        }
        
    except Exception:
        return None

if __name__ == "__main__":
    main()

七、JavaScript算法源码

// Node.js环境下的输入处理
const readline = require('readline');

/**
 * 主函数:处理输入并调用相应的编码或解码函数
 */
function main() {
    const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout
    });
    
    let lineCount = 0;
    let command = 0;
    
    rl.on('line', (input) => {
        if (lineCount === 0) {
            // 读取命令:1表示编码,2表示解码
            command = parseInt(input);
            lineCount++;
        } else {
            // 读取待处理的数据
            if (command === 1) {
                // 执行编码操作
                console.log(encode(input));
            } else if (command === 2) {
                // 执行解码操作
                console.log(decode(input));
            }
            rl.close();
        }
    });
}

/**
 * 编码函数:将输入的数据格式转换为编码格式
 * @param {string} inputStr 输入字符串,格式为[位置,类型,值],...
 * @returns {string} 编码后的字符串
 */
function encode(inputStr) {
    try {
        // 检查输入长度限制
        if (inputStr.length > 1000) {
            return "ENCODE_ERROR";
        }
        
        const result = [];
        const dataItems = parseDataItems(inputStr);
        
        // 处理每个数据项
        for (const item of dataItems) {
            const encoded = encodeItem(item);
            if (encoded !== "ENCODE_ERROR") {
                result.push(encoded);
            }
        }
        
        return result.join('');
    } catch (error) {
        return "ENCODE_ERROR";
    }
}

/**
 * 解码函数:将编码格式转换为原始数据格式
 * @param {string} inputStr 编码后的字符串
 * @returns {string} 解码后的字符串
 */
function decode(inputStr) {
    try {
        // 检查输入长度限制
        if (inputStr.length > 1000) {
            return "DECODE_ERROR";
        }
        
        const decodedItems = [];
        let index = 0;
        
        // 逐个解析编码数据
        while (index < inputStr.length) {
            try {
                const decodedData = decodeItem(inputStr, index);
                if (decodedData) {
                    decodedItems.push(decodedData.decodedString);
                    index = decodedData.nextIndex;
                } else {
                    break;
                }
            } catch (error) {
                // 数据区异常则跳过,寻找下一个可能的数据开始位置
                index++;
            }
        }
        
        return decodedItems.join(',');
    } catch (error) {
        return "DECODE_ERROR";
    }
}

/**
 * 解析输入字符串中的数据项列表
 * @param {string} inputStr 输入字符串
 * @returns {Array<string>} 数据项列表
 */
function parseDataItems(inputStr) {
    const items = [];
    let level = 0;
    let start = 0;
    
    for (let i = 0; i < inputStr.length; i++) {
        const c = inputStr[i];
        if (c === '[') {
            level++;
        } else if (c === ']') {
            level--;
            if (level === 0) {
                // 找到一个完整的数据项
                items.push(inputStr.substring(start, i + 1));
                // 跳过可能的逗号
                if (i + 1 < inputStr.length && inputStr[i + 1] === ',') {
                    i++;
                }
                start = i + 1;
            }
        }
    }
    
    return items;
}

/**
 * 编码单个数据项
 * @param {string} item 数据项字符串,格式为[位置,类型,值]
 * @returns {string} 编码后的字符串
 */
function encodeItem(item) {
    try {
        // 去掉首尾的方括号
        const content = item.substring(1, item.length - 1);
        
        // 解析位置、类型、值
        const parsed = parseItem(content);
        if (!parsed) {
            return "ENCODE_ERROR";
        }
        
        // 获取类型编码
        const typeCode = getTypeCode(parsed.type);
        if (typeCode === -1) {
            return "ENCODE_ERROR"; // 不支持的类型
        }
        
        let data;
        if (parsed.type === "Compose") {
            // Compose类型需要递归编码内部数据
            data = encode(parsed.value);
            if (data === "ENCODE_ERROR") {
                return "ENCODE_ERROR";
            }
        } else {
            data = parsed.value;
        }
        
        // 验证数据格式:只允许数字、大写字母、小写字母、空格
        if (!isValidData(data) && parsed.type !== "Compose") {
            return "ENCODE_ERROR";
        }
        
        // 构建编码结果:位置#类型#长度#数据
        return `${parsed.position}#${typeCode}#${data.length}#${data}`;
        
    } catch (error) {
        return "ENCODE_ERROR";
    }
}

/**
 * 解析数据项内容
 * @param {string} content 数据项内容(不含方括号)
 * @returns {Object|null} 解析后的数据对象
 */
function parseItem(content) {
    try {
        // 找到第一个逗号,分离位置
        const firstComma = content.indexOf(',');
        if (firstComma === -1) {
            return null;
        }
        
        const position = content.substring(0, firstComma);
        
        // 对于不同类型,需要特殊处理,因为值中可能包含逗号
        const typeStart = firstComma + 1;
        let typeEnd = -1;
        
        // 查找类型结束位置
        if (content.startsWith("Compose", typeStart)) {
            typeEnd = typeStart + 7; // "Compose".length
        } else if (content.startsWith("String", typeStart)) {
            typeEnd = typeStart + 6; // "String".length
        } else if (content.startsWith("Integer", typeStart)) {
            typeEnd = typeStart + 7; // "Integer".length
        }
        
        if (typeEnd === -1 || typeEnd >= content.length || content[typeEnd] !== ',') {
            return null;
        }
        
        const type = content.substring(typeStart, typeEnd);
        const value = content.substring(typeEnd + 1);
        
        return { position, type, value };
    } catch (error) {
        return null;
    }
}

/**
 * 获取类型对应的编码
 * @param {string} typeName 类型名称
 * @returns {number} 类型编码,-1表示不支持的类型
 */
function getTypeCode(typeName) {
    const typeCodes = {
        "Integer": 0,
        "String": 1,
        "Compose": 2
    };
    return typeCodes[typeName] !== undefined ? typeCodes[typeName] : -1;
}

/**
 * 获取编码对应的类型名称
 * @param {number} code 类型编码
 * @returns {string|null} 类型名称
 */
function getTypeName(code) {
    const typeNames = {
        0: "Integer",
        1: "String",
        2: "Compose"
    };
    return typeNames[code] || null;
}

/**
 * 验证数据是否有效(只包含数字、大写字母、小写字母、空格)
 * @param {string} data 待验证的数据
 * @returns {boolean} 是否有效
 */
function isValidData(data) {
    for (const c of data) {
        if (!/[a-zA-Z0-9 ]/.test(c)) {
            return false;
        }
    }
    return true;
}

/**
 * 解码单个数据项
 * @param {string} inputStr 编码字符串
 * @param {number} startIndex 开始位置
 * @returns {Object|null} 解码结果对象,包含解码字符串和下一个位置
 */
function decodeItem(inputStr, startIndex) {
    try {
        let index = startIndex;
        
        // 解析位置
        const firstSharp = inputStr.indexOf('#', index);
        if (firstSharp === -1) {
            return null;
        }
        const position = inputStr.substring(index, firstSharp);
        
        // 解析类型编码
        index = firstSharp + 1;
        const secondSharp = inputStr.indexOf('#', index);
        if (secondSharp === -1) {
            return null;
        }
        const typeCode = parseInt(inputStr.substring(index, secondSharp));
        const typeName = getTypeName(typeCode);
        if (!typeName) {
            return null;
        }
        
        // 解析长度
        index = secondSharp + 1;
        const thirdSharp = inputStr.indexOf('#', index);
        if (thirdSharp === -1) {
            return null;
        }
        const length = parseInt(inputStr.substring(index, thirdSharp));
        
        // 解析数据
        index = thirdSharp + 1;
        if (index + length > inputStr.length) {
            return null;
        }
        const data = inputStr.substring(index, index + length);
        
        let decodedString;
        if (typeName === "Compose") {
            // Compose类型需要递归解码
            const innerDecoded = decode(data);
            if (innerDecoded === "DECODE_ERROR") {
                return null;
            }
            decodedString = `[${position},${typeName},${innerDecoded}]`;
        } else {
            decodedString = `[${position},${typeName},${data}]`;
        }
        
        return {
            decodedString: decodedString,
            nextIndex: index + length
        };
        
    } catch (error) {
        return null;
    }
}

// 导出函数供外部使用
if (typeof module !== 'undefined' && module.exports) {
    module.exports = {
        encode,
        decode,
        runTests
    };
}

// 如果直接运行此文件,则执行主函数
if (require.main === module) {
    main();
}

八、C算法源码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

// 定义常量
#define MAX_INPUT_SIZE 1001
#define MAX_ITEMS 100
#define MAX_ITEM_SIZE 1001

// 数据项结构体
typedef struct {
    char position[10];  // 位置字符串
    char type[10];      // 类型字符串
    char value[1000];   // 值字符串
} ParsedItem;

// 解码结果结构体
typedef struct {
    char decoded_string[1000];  // 解码后的字符串
    int next_index;             // 下一个解析位置
    int valid;                  // 是否有效
} DecodedData;

// 函数声明
char* encode(const char* input);
char* decode(const char* input);
int parse_data_items(const char* input, char items[][MAX_ITEM_SIZE]);
char* encode_item(const char* item);
int parse_item(const char* content, ParsedItem* parsed);
int get_type_code(const char* type_name);
const char* get_type_name(int code);
int is_valid_data(const char* data);
DecodedData decode_item(const char* input, int start_index);

/**
 * 主函数:处理输入并调用相应的编码或解码函数
 */
int main() {
    int command;         // 命令:1表示编码,2表示解码
    char input[MAX_INPUT_SIZE];  // 输入数据
    
    // 读取命令
    scanf("%d", &command);
    getchar(); // 消费换行符
    
    // 读取待处理的数据
    fgets(input, sizeof(input), stdin);
    // 移除换行符
    input[strcspn(input, "\n")] = 0;
    
    if (command == 1) {
        // 执行编码操作
        char* result = encode(input);
        printf("%s\n", result);
        free(result);
    } else if (command == 2) {
        // 执行解码操作
        char* result = decode(input);
        printf("%s\n", result);
        free(result);
    }
    
    return 0;
}

/**
 * 编码函数:将输入的数据格式转换为编码格式
 * @param input 输入字符串,格式为[位置,类型,值],...
 * @return 编码后的字符串(需要调用者释放内存)
 */
char* encode(const char* input) {
    // 分配结果字符串内存
    char* result = (char*)malloc(MAX_INPUT_SIZE * 2);
    result[0] = '\0';
    
    // 检查输入长度限制
    if (strlen(input) > 1000) {
        strcpy(result, "ENCODE_ERROR");
        return result;
    }
    
    // 解析数据项
    char items[MAX_ITEMS][MAX_ITEM_SIZE];
    int item_count = parse_data_items(input, items);
    
    // 处理每个数据项
    for (int i = 0; i < item_count; i++) {
        char* encoded = encode_item(items[i]);
        if (strcmp(encoded, "ENCODE_ERROR") != 0) {
            strcat(result, encoded);
        }
        free(encoded);
    }
    
    return result;
}

/**
 * 解码函数:将编码格式转换为原始数据格式
 * @param input 编码后的字符串
 * @return 解码后的字符串(需要调用者释放内存)
 */
char* decode(const char* input) {
    // 分配结果字符串内存
    char* result = (char*)malloc(MAX_INPUT_SIZE * 2);
    result[0] = '\0';
    
    // 检查输入长度限制
    if (strlen(input) > 1000) {
        strcpy(result, "DECODE_ERROR");
        return result;
    }
    
    int index = 0;
    int first_item = 1;  // 标记是否为第一个项目(用于添加逗号分隔符)
    
    // 逐个解析编码数据
    while (index < (int)strlen(input)) {
        DecodedData data = decode_item(input, index);
        if (data.valid) {
            if (!first_item) {
                strcat(result, ",");
            }
            strcat(result, data.decoded_string);
            index = data.next_index;
            first_item = 0;
        } else {
            // 数据区异常则跳过,寻找下一个可能的数据开始位置
            index++;
        }
    }
    
    return result;
}

/**
 * 解析输入字符串中的数据项列表
 * @param input 输入字符串
 * @param items 存储解析结果的数组
 * @return 解析到的数据项数量
 */
int parse_data_items(const char* input, char items[][MAX_ITEM_SIZE]) {
    int item_count = 0;
    int level = 0;
    int start = 0;
    int len = strlen(input);
    
    for (int i = 0; i < len; i++) {
        char c = input[i];
        if (c == '[') {
            level++;
        } else if (c == ']') {
            level--;
            if (level == 0) {
                // 找到一个完整的数据项
                int item_len = i - start + 1;
                strncpy(items[item_count], input + start, item_len);
                items[item_count][item_len] = '\0';
                item_count++;
                
                // 跳过可能的逗号
                if (i + 1 < len && input[i + 1] == ',') {
                    i++;
                }
                start = i + 1;
            }
        }
    }
    
    return item_count;
}

/**
 * 编码单个数据项
 * @param item 数据项字符串,格式为[位置,类型,值]
 * @return 编码后的字符串(需要调用者释放内存)
 */
char* encode_item(const char* item) {
    char* result = (char*)malloc(MAX_INPUT_SIZE);
    
    // 去掉首尾的方括号
    int len = strlen(item);
    char* content = (char*)malloc(len - 1);
    strncpy(content, item + 1, len - 2);
    content[len - 2] = '\0';
    
    // 解析位置、类型、值
    ParsedItem parsed;
    if (!parse_item(content, &parsed)) {
        strcpy(result, "ENCODE_ERROR");
        free(content);
        return result;
    }
    
    // 获取类型编码
    int type_code = get_type_code(parsed.type);
    if (type_code == -1) {
        strcpy(result, "ENCODE_ERROR"); // 不支持的类型
        free(content);
        return result;
    }
    
    char data[1000];
    if (strcmp(parsed.type, "Compose") == 0) {
        // Compose类型需要递归编码内部数据
        char* encoded_data = encode(parsed.value);
        if (strcmp(encoded_data, "ENCODE_ERROR") == 0) {
            strcpy(result, "ENCODE_ERROR");
            free(content);
            free(encoded_data);
            return result;
        }
        strcpy(data, encoded_data);
        free(encoded_data);
    } else {
        strcpy(data, parsed.value);
    }
    
    // 验证数据格式:只允许数字、大写字母、小写字母、空格
    if (!is_valid_data(data) && strcmp(parsed.type, "Compose") != 0) {
        strcpy(result, "ENCODE_ERROR");
        free(content);
        return result;
    }
    
    // 构建编码结果:位置#类型#长度#数据
    sprintf(result, "%s#%d#%d#%s", parsed.position, type_code, (int)strlen(data), data);
    
    free(content);
    return result;
}

/**
 * 解析数据项内容
 * @param content 数据项内容(不含方括号)
 * @param parsed 解析结果存储位置
 * @return 是否解析成功
 */
int parse_item(const char* content, ParsedItem* parsed) {
    // 找到第一个逗号,分离位置
    char* first_comma = strchr(content, ',');
    if (!first_comma) {
        return 0;
    }
    
    int position_len = first_comma - content;
    strncpy(parsed->position, content, position_len);
    parsed->position[position_len] = '\0';
    
    // 对于不同类型,需要特殊处理,因为值中可能包含逗号
    const char* type_start = first_comma + 1;
    const char* type_end = NULL;
    
    // 查找类型结束位置
    if (strncmp(type_start, "Compose", 7) == 0) {
        type_end = type_start + 7;
    } else if (strncmp(type_start, "String", 6) == 0) {
        type_end = type_start + 6;
    } else if (strncmp(type_start, "Integer", 7) == 0) {
        type_end = type_start + 7;
    }
    
    if (!type_end || *type_end != ',') {
        return 0;
    }
    
    int type_len = type_end - type_start;
    strncpy(parsed->type, type_start, type_len);
    parsed->type[type_len] = '\0';
    
    strcpy(parsed->value, type_end + 1);
    
    return 1;
}

/**
 * 获取类型对应的编码
 * @param type_name 类型名称
 * @return 类型编码,-1表示不支持的类型
 */
int get_type_code(const char* type_name) {
    if (strcmp(type_name, "Integer") == 0) {
        return 0;
    } else if (strcmp(type_name, "String") == 0) {
        return 1;
    } else if (strcmp(type_name, "Compose") == 0) {
        return 2;
    }
    return -1; // 不支持的类型
}

/**
 * 获取编码对应的类型名称
 * @param code 类型编码
 * @return 类型名称
 */
const char* get_type_name(int code) {
    switch (code) {
        case 0: return "Integer";
        case 1: return "String";
        case 2: return "Compose";
        default: return NULL;
    }
}

/**
 * 验证数据是否有效(只包含数字、大写字母、小写字母、空格)
 * @param data 待验证的数据
 * @return 是否有效
 */
int is_valid_data(const char* data) {
    for (int i = 0; data[i] != '\0'; i++) {
        char c = data[i];
        if (!isalnum(c) && c != ' ') {
            return 0;
        }
    }
    return 1;
}

/**
 * 解码单个数据项
 * @param input 编码字符串
 * @param start_index 开始位置
 * @return 解码结果结构体
 */
DecodedData decode_item(const char* input, int start_index) {
    DecodedData result;
    result.valid = 0;  // 默认无效
    
    int index = start_index;
    int len = strlen(input);
    
    // 解析位置
    char* first_sharp = strchr(input + index, '#');
    if (!first_sharp) {
        return result;
    }
    
    char position[10];
    int position_len = first_sharp - (input + index);
    strncpy(position, input + index, position_len);
    position[position_len] = '\0';
    
    // 解析类型编码
    index = first_sharp - input + 1;
    char* second_sharp = strchr(input + index, '#');
    if (!second_sharp) {
        return result;
    }
    
    char type_code_str[10];
    int type_code_len = second_sharp - (input + index);
    strncpy(type_code_str, input + index, type_code_len);
    type_code_str[type_code_len] = '\0';
    int type_code = atoi(type_code_str);
    
    const char* type_name = get_type_name(type_code);
    if (!type_name) {
        return result;
    }
    
    // 解析长度
    index = second_sharp - input + 1;
    char* third_sharp = strchr(input + index, '#');
    if (!third_sharp) {
        return result;
    }
    
    char length_str[10];
    int length_str_len = third_sharp - (input + index);
    strncpy(length_str, input + index, length_str_len);
    length_str[length_str_len] = '\0';
    int length = atoi(length_str);
    
    // 解析数据
    index = third_sharp - input + 1;
    if (index + length > len) {
        return result;
    }
    
    char data[1000];
    strncpy(data, input + index, length);
    data[length] = '\0';
    
    if (strcmp(type_name, "Compose") == 0) {
        // Compose类型需要递归解码
        char* inner_decoded = decode(data);
        if (strcmp(inner_decoded, "DECODE_ERROR") == 0) {
            free(inner_decoded);
            return result;
        }
        sprintf(result.decoded_string, "[%s,%s,%s]", position, type_name, inner_decoded);
        free(inner_decoded);
    } else {
        sprintf(result.decoded_string, "[%s,%s,%s]", position, type_name, data);
    }
    
    result.next_index = index + length;
    result.valid = 1;
    
    return result;
}

九、C++算法源码

#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <algorithm>
#include <cctype>

// 数据项结构体
struct ParsedItem {
    std::string position;  // 位置字符串
    std::string type;      // 类型字符串
    std::string value;     // 值字符串
    
    // 构造函数
    ParsedItem(const std::string& pos, const std::string& t, const std::string& val)
        : position(pos), type(t), value(val) {}
};

// 解码结果结构体
struct DecodedData {
    std::string decodedString;  // 解码后的字符串
    int nextIndex;              // 下一个解析位置
    bool valid;                 // 是否有效
    
    // 构造函数
    DecodedData() : nextIndex(0), valid(false) {}
    DecodedData(const std::string& decoded, int next, bool v)
        : decodedString(decoded), nextIndex(next), valid(v) {}
};

// 函数声明
std::string encode(const std::string& input);
std::string decode(const std::string& input);
std::vector<std::string> parseDataItems(const std::string& input);
std::string encodeItem(const std::string& item);
ParsedItem parseItem(const std::string& content);
int getTypeCode(const std::string& typeName);
std::string getTypeName(int code);
bool isValidData(const std::string& data);
DecodedData decodeItem(const std::string& input, int startIndex);

/**
 * 主函数:处理输入并调用相应的编码或解码函数
 */
int main() {
    int command;                    // 命令:1表示编码,2表示解码
    std::string input;              // 输入数据
    
    // 读取命令
    std::cin >> command;
    std::cin.ignore(); // 忽略换行符
    
    // 读取待处理的数据
    std::getline(std::cin, input);
    
    if (command == 1) {
        // 执行编码操作
        std::cout << encode(input) << std::endl;
    } else if (command == 2) {
        // 执行解码操作
        std::cout << decode(input) << std::endl;
    }
    
    return 0;
}

/**
 * 编码函数:将输入的数据格式转换为编码格式
 * @param input 输入字符串,格式为[位置,类型,值],...
 * @return 编码后的字符串
 */
std::string encode(const std::string& input) {
    try {
        // 检查输入长度限制
        if (input.length() > 1000) {
            return "ENCODE_ERROR";
        }
        
        std::string result;
        std::vector<std::string> dataItems = parseDataItems(input);
        
        // 处理每个数据项
        for (const std::string& item : dataItems) {
            std::string encoded = encodeItem(item);
            if (encoded != "ENCODE_ERROR") {
                result += encoded;
            }
        }
        
        return result;
    } catch (...) {
        return "ENCODE_ERROR";
    }
}

/**
 * 解码函数:将编码格式转换为原始数据格式
 * @param input 编码后的字符串
 * @return 解码后的字符串
 */
std::string decode(const std::string& input) {
    try {
        // 检查输入长度限制
        if (input.length() > 1000) {
            return "DECODE_ERROR";
        }
        
        std::vector<std::string> decodedItems;
        int index = 0;
        
        // 逐个解析编码数据
        while (index < static_cast<int>(input.length())) {
            try {
                DecodedData data = decodeItem(input, index);
                if (data.valid) {
                    decodedItems.push_back(data.decodedString);
                    index = data.nextIndex;
                } else {
                    break;
                }
            } catch (...) {
                // 数据区异常则跳过,寻找下一个可能的数据开始位置
                index++;
            }
        }
        
        // 将解码项用逗号连接
        std::string result;
        for (size_t i = 0; i < decodedItems.size(); ++i) {
            if (i > 0) result += ",";
            result += decodedItems[i];
        }
        
        return result;
    } catch (...) {
        return "DECODE_ERROR";
    }
}

/**
 * 解析输入字符串中的数据项列表
 * @param input 输入字符串
 * @return 数据项列表
 */
std::vector<std::string> parseDataItems(const std::string& input) {
    std::vector<std::string> items;
    int level = 0;
    int start = 0;
    
    for (int i = 0; i < static_cast<int>(input.length()); i++) {
        char c = input[i];
        if (c == '[') {
            level++;
        } else if (c == ']') {
            level--;
            if (level == 0) {
                // 找到一个完整的数据项
                items.push_back(input.substr(start, i - start + 1));
                // 跳过可能的逗号
                if (i + 1 < static_cast<int>(input.length()) && input[i + 1] == ',') {
                    i++;
                }
                start = i + 1;
            }
        }
    }
    
    return items;
}

/**
 * 编码单个数据项
 * @param item 数据项字符串,格式为[位置,类型,值]
 * @return 编码后的字符串
 */
std::string encodeItem(const std::string& item) {
    try {
        // 去掉首尾的方括号
        std::string content = item.substr(1, item.length() - 2);
        
        // 解析位置、类型、值
        ParsedItem parsed = parseItem(content);
        if (parsed.position.empty()) {
            return "ENCODE_ERROR";
        }
        
        // 获取类型编码
        int typeCode = getTypeCode(parsed.type);
        if (typeCode == -1) {
            return "ENCODE_ERROR"; // 不支持的类型
        }
        
        std::string data;
        if (parsed.type == "Compose") {
            // Compose类型需要递归编码内部数据
            data = encode(parsed.value);
            if (data == "ENCODE_ERROR") {
                return "ENCODE_ERROR";
            }
        } else {
            data = parsed.value;
        }
        
        // 验证数据格式:只允许数字、大写字母、小写字母、空格
        if (!isValidData(data) && parsed.type != "Compose") {
            return "ENCODE_ERROR";
        }
        
        // 构建编码结果:位置#类型#长度#数据
        return parsed.position + "#" + std::to_string(typeCode) + "#" + 
               std::to_string(data.length()) + "#" + data;
        
    } catch (...) {
        return "ENCODE_ERROR";
    }
}

/**
 * 解析数据项内容
 * @param content 数据项内容(不含方括号)
 * @return 解析后的数据结构体
 */
ParsedItem parseItem(const std::string& content) {
    try {
        // 找到第一个逗号,分离位置
        size_t firstComma = content.find(',');
        if (firstComma == std::string::npos) {
            return ParsedItem("", "", ""); // 返回空的ParsedItem表示失败
        }
        
        std::string position = content.substr(0, firstComma);
        
        // 对于不同类型,需要特殊处理,因为值中可能包含逗号
        size_t typeStart = firstComma + 1;
        size_t typeEnd = std::string::npos;
        
        // 查找类型结束位置
        if (content.substr(typeStart, 7) == "Compose") {
            typeEnd = typeStart + 7;
        } else if (content.substr(typeStart, 6) == "String") {
            typeEnd = typeStart + 6;
        } else if (content.substr(typeStart, 7) == "Integer") {
            typeEnd = typeStart + 7;
        }
        
        if (typeEnd == std::string::npos || typeEnd >= content.length() || content[typeEnd] != ',') {
            return ParsedItem("", "", ""); // 返回空的ParsedItem表示失败
        }
        
        std::string type = content.substr(typeStart, typeEnd - typeStart);
        std::string value = content.substr(typeEnd + 1);
        
        return ParsedItem(position, type, value);
    } catch (...) {
        return ParsedItem("", "", ""); // 返回空的ParsedItem表示失败
    }
}

/**
 * 获取类型对应的编码
 * @param typeName 类型名称
 * @return 类型编码,-1表示不支持的类型
 */
int getTypeCode(const std::string& typeName) {
    if (typeName == "Integer") {
        return 0;
    } else if (typeName == "String") {
        return 1;
    } else if (typeName == "Compose") {
        return 2;
    }
    return -1; // 不支持的类型
}

/**
 * 获取编码对应的类型名称
 * @param code 类型编码
 * @return 类型名称
 */
std::string getTypeName(int code) {
    switch (code) {
        case 0: return "Integer";
        case 1: return "String";
        case 2: return "Compose";
        default: return "";
    }
}

/**
 * 验证数据是否有效(只包含数字、大写字母、小写字母、空格)
 * @param data 待验证的数据
 * @return 是否有效
 */
bool isValidData(const std::string& data) {
    for (char c : data) {
        if (!std::isalnum(c) && c != ' ') {
            return false;
        }
    }
    return true;
}

/**
 * 解码单个数据项
 * @param input 编码字符串
 * @param startIndex 开始位置
 * @return 解码结果结构体
 */
DecodedData decodeItem(const std::string& input, int startIndex) {
    try {
        int index = startIndex;
        
        // 解析位置
        size_t firstSharp = input.find('#', index);
        if (firstSharp == std::string::npos) {
            return DecodedData();
        }
        std::string position = input.substr(index, firstSharp - index);
        
        // 解析类型编码
        index = firstSharp + 1;
        size_t secondSharp = input.find('#', index);
        if (secondSharp == std::string::npos) {
            return DecodedData();
        }
        int typeCode = std::stoi(input.substr(index, secondSharp - index));
        std::string typeName = getTypeName(typeCode);
        if (typeName.empty()) {
            return DecodedData();
        }
        
        // 解析长度
        index = secondSharp + 1;
        size_t thirdSharp = input.find('#', index);
        if (thirdSharp == std::string::npos) {
            return DecodedData();
        }
        int length = std::stoi(input.substr(index, thirdSharp - index));
        
        // 解析数据
        index = thirdSharp + 1;
        if (index + length > static_cast<int>(input.length())) {
            return DecodedData();
        }
        std::string data = input.substr(index, length);
        
        std::string decodedString;
        if (typeName == "Compose") {
            // Compose类型需要递归解码
            std::string innerDecoded = decode(data);
            if (innerDecoded == "DECODE_ERROR") {
                return DecodedData();
            }
            decodedString = "[" + position + "," + typeName + "," + innerDecoded + "]";
        } else {
            decodedString = "[" + position + "," + typeName + "," + data + "]";
        }
        
        return DecodedData(decodedString, index + length, true);
        
    } catch (...) {
        return DecodedData();
    }
}

/**
 * 运行测试用例验证代码正确性
 */
void runTests() {
    std::cout << "开始测试...\n" << std::endl;
    
    // 测试用例1:编码测试
    std::cout << "=== 测试用例1(编码)===" << std::endl;
    std::string test1 = "[1,String,I am Mary],[2,Integer,23],[4,Compose,[1,String,I am Kitty],[2,Integer,44]]";
    std::string result1 = encode(test1);
    std::cout << "输入: " << test1 << std::endl;
    std::cout << "输出: " << result1 << std::endl;
    std::cout << "预期: 1#1#9#I am Mary2#0#2#234#2#25#1#1#10#I am Kitty2#0#2#44\n" << std::endl;
    
    // 测试用例2:解码测试
    std::cout << "=== 测试用例2(解码)===" << std::endl;
    std::string test2 = "1#1#9#I am Mary2#0#2#233#0#3#8794#2#25#1#1#10#I am Kitty2#0#2#44";
    std::string result2 = decode(test2);
    std::cout << "输入: " << test2 << std::endl;
    std::cout << "输出: " << result2 << std::endl;
    std::cout << "预期: [1,String,I am Mary],[2,Integer,23],[3,Integer,879],[4,Compose,[1,String,I am Kitty],[2,Integer,44]]\n" << std::endl;
}

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

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

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

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

哪 吒

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

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

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

打赏作者

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

抵扣说明:

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

余额充值