通过率 64% · 提交 364 · 通过 233
小慕在开发一个网络协议解析模块时,遇到了TLV编码格式的数据流。TLV编码按Tag、Length、Value的格式组织数据。 一段中的每个数据单元用tag标识,tag在码流中唯一不重复;length表示该数据单元value的长度;value表示该数据单元的实际内容。码流以某个数据单元的tag开头,tag固定占一个字节,length固定占两个字节,字节序为。 现在,小慕需要从给定的TLV格式编码的码流中,解析出指定tag对应的value值。 输入码流的16进制字符串中不包含小写字母,要求输出的16进制字符串中也不要包含小写字母。码流字符串的最大长度不超过50000个字节。
这类题属于华为 OD 机考真题方向中「100分 / 数组」方向的高频题型,通常考察对「100分 / 数组」的建模能力与边界条件处理。掌握本题的解题思路后,可举一反三应对同类真题方向,稳步提升机考通过率。
提示:带虚线的词点一下有通俗解释。
第一行为第一个字符串 ,表示待解码信元的 tag;输入第二行为一个字符串, 表示待解码的 16 进制码流;字节之间用 空格 分割。
输出一个字符串,表示待解码信元以 16 进制表示的 value。
示例 1
输入示例
31 32 01 00 AE 90 02 00 01 02 30 03 00 AB 32 31 31 02 00 32 33 33 01 00 CC
输出示例
32 33
时间限制 1000 ms · 内存限制 128 MB
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。
又是一道比较难读懂的题目,需要一些前置知识的理解。
这道题涉及一个前置知识,大端序和小端序。 这两种排序都是字节序,表示的是数据字节在内存中的存储方式。
看起来有点拗口,但只需要记住:大端序从左到右排列符合人类阅读习惯,小端序从右到左排列不符合人类阅读习惯即可。
下图显示了示例的码流的解码过程: 蓝、绿、红构成的一整段内容表示一个信元,其中:
tagvalue 的长度value 的内容我们要做的事情,就是找到 tag 为第一行输入的 target_tag 的那个信元,所对应的 value 的内容。
本题剩余内容,只需要按照题目要求进行模拟即可。
我们可以构建一个 help 辅助函数,用于一个特定信元的解码。 其中,传入的参数 stream 为输入码流数组,idx 为当前信元标识在数组中的索引。容易得到代码:
在这个函数外部,由于 idx 增加的幅度是根据每次解码后得到的信元内容的长度 length 决定的,并不是一个固定值,我们需要在 while 循环中进行遍历。
循环条件为,idx 在 stream 中对应的字符串不是目标信元 target_tag。 在循环中,我们调用 help 函数,得到当前信元的标识 cur_tag 和长度 cur_length。
信元标识和长度一共占 3 位,信元中的信息占 cur_length 位,因此下一个信元的标识 tag 的位置位于 stream 数组中的 idx + 3 + cur_length 处。综上可以得到代码:
退出 while 循环后,idx 所在的位置即为目标信元 target_tag 的标识。 再一次调用 help 函数,进行信元解码,得到目标信元的长度 cur_length。 此时 stream 中,从索引 idx+3 到 idx+3+cur_length 位置的切片,就是目标信元的内容,将其输出即为最终的答案。
复杂度分析 设 n 为码流中的字节数(即 stream 数组的长度)。主体是一个 while 循环,从 idx = 0 出发,每轮调用一次 help 函数:help 只做「取 tag、按小端序把两个长度字节拼成十六进制串、转成十进制」这几步常数操作,是 O(1);随后 idx 直接跳到下一个信元的 tag 位置(idx += 3 + cur_length)。也就是说循环不是逐字节挪动,而是以信元为单位向前跳,每个信元最多被访问一次,所有跳跃加起来最多覆盖整条码流,因此查找目标 tag 的过程是 O(n)。找到后再做一次 O(1) 的解码,并取出长度为 cur_length 的切片拼接输出,这一步最多 O(n)。所以总时间复杂度为 O(n),瓶颈是按信元跳跃扫过码流这一遍。空间上,stream 数组本身占 O(n),解析过程只用了 idx、cur_tag、cur_length 几个变量,除输入和输出切片外的额外空间为 O(1)。
登录后可查看你在本题的历史提交,以及每次的各用例通过情况。
© 2026 广州慕课网络科技有限公司 · 吴师兄学算法官网 版权所有