专栏导读
本专栏收录于《华为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]]
五、解题思路
- 使用括号匹配技术解析每个[位置,类型,值]数据项
- 类型映射:Integer→0, String→1, Compose→2
- 按格式位置#类型编码#数据长度#数据生成编码
- 对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算法的适用场景,发现新题目,随时更新。