目录
- 专栏导读
- 一、题目描述
- 二、输入描述
- 三、输出描述
- 四、解题思路
- 五、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在线答疑。