
目录
- 专栏导读
- 一、题目描述
- 二、输入描述
- 三、输出描述
- 四、解题思路
- 五、Java算法源码
- 六、效果展示
- 1、输入
- 2、输出
- 3、说明
 
 
华为OD机试 2023B卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试(JAVA)真题(A卷+B卷)》。
刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。
一、题目描述
两端通过TLV格式的报文来通信,现在收到对端的一个TLV格式的消息包,要求生成匹配后的(tag,length,valueOffset)列表。
 具体要求如下:
- 消息包中多组tag,length,value紧密排列,其中tag,length各种1字节(uint8_t),value所占字节数等于length的值。
- 结果数组中tag值已知,需要田中每个tag对应数据的length和valueOffset值(valueOffset为value在原消息包中的起始偏移量(从0开始,以字节为单位)),即将消息包中的tag与结果数组中的tag进行匹配(可能存在匹配失败的情况,若结果数组中tag在消息包中找不到,则length和valueOffset都为0)。
- 消息包和结果数组职工的tag值都按升序排序,且不重复。
- 此消息包未被篡改,但尾部可能不完整,不完整的一组TLV请丢弃掉。
二、输入描述
第一行:一个字符,代表收到的消息包。字符串长度在10000以内。
- 说明1:字符串使用十六进制文本格式(字母为大写)来展示消息包的数据,如0F04ABABABAB代表一组TLV:前两个字符(OF)代表tag值为15,接下来两个字符(04)代表length值为4字节,接下来8个字符即为4字节的value。
- 说明2:输入字符串中,每一组TLV紧密排列,中间无空格等分隔符
第二行:需要匹配的tag数量n(0 < n < 1000)
 后面N行:需要匹配n个tag值(十进制表示),递增排列。
三、输出描述
和需要匹配的n个tag对应的n行匹配结果,每一行由长度和偏移量组成。
四、解题思路
- 第一行:一个字符,代表收到的消息包;
- 第二行:需要匹配的tag数量n(0 < n < 1000);
- 后面N行:需要匹配n个tag值(十进制表示),递增排列;
- 定义哈希表,存储tag对应的length和valueOffset;
- 解析字符串msg,初始化哈希表; 
  - 将16进制字符串转换为整数;
- 计算valueOffset;
- 跳过value,更新i;
- 如果i超出msg长度,跳出循环;
- 将tag、length、valueOffset存入tagMap中;
 
- 遍历tags,输出匹配结果。
五、Java算法源码
package com.guor.od;
import java.util.*;
public class OdTest {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        // 收到的消息包
        String msg = sc.next();
        // 需要匹配的tag数量n
        int n = sc.nextInt();
        // 后面N行:需要匹配n个tag值(十进制表示),递增排列
        int[] tags = new int[n];
        for (int i = 0; i < n; i++) {
            tags[i] = sc.nextInt();
        }
        // 定义哈希表,存储tag对应的length和valueOffset
        Map<Integer, List<Integer>> tagMap = new HashMap<>();
        // 解析字符串msg,初始化哈希表
        for (int i = 0; i + 3 < msg.length(); i++) {
            int tag, len, valueOffset;
            String tagStr = msg.substring(i, i + 2);
            String lenStr = msg.substring(i + 2, i + 4);
            // 将16进制字符串转换为整数
            tag = Integer.parseInt(tagStr, 16);
            len = Integer.parseInt(lenStr, 16);
            // 计算valueOffset
            valueOffset = (i + 5) / 2;
            // 跳过value,更新i
            i += 3 + len * 2;
            // 如果i超出msg长度,跳出循环
            if (i >= msg.length()) {
                break;
            }
            // 将tag、length、valueOffset存入tagMap中
            tagMap.put(tag, Arrays.asList(len, valueOffset));
        }
        // 遍历tags,输出匹配结果
        for (int tag : tags) {
            if (tagMap.containsKey(tag)) {
                List<Integer> tmp = tagMap.get(tag);
                int len = tmp.get(0);
                int valueOffset = tmp.get(1);
                System.out.println(len + " " + valueOffset);
            } else {
                System.out.println("0 0");
            }
        }
    }
}
六、效果展示
1、输入
0F04ABABABAB
 1
 15
2、输出
4 2
3、说明
tag15(十六进制0F)对应数据的长度为4,其value从第三个字节开始,因此偏移量为2。

🏆下一篇:华为OD机试真题 Java 实现【路灯照明问题】【2022Q4 100分】,感谢fly晨发现这个问题,并提供更优质的算法
🏆本文收录于,华为OD机试(JAVA)真题(A卷+B卷)
刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。


















![[C++]3.类和对象下(this指针补充)+ 类和对象中构造函数和析构函数。](https://img-blog.csdnimg.cn/7e0c743553284382aa8a320c83fb4ab5.gif)

