【华为OD题库-082】TLV解析II-Java

题目

两端通过TLVQ格式的报文来通信,现在收到对端的一个TLV格式的消息包,要求生成匹配后的(tag,length,valueOffset)列表。具体要求如下:

(1)消息包中多组tag、length、value紧密排列,其中tag,length各占1字节(uint8),value所占字节数等于length的值

(2) 结果数组中tag值已知,需要填充每个tag对应数据的length和valueOffset值(valueOffset为value在原消息包中的起始偏移量(从0开始,以字节为单位),即将消息包中的tag与结果数组中的tag进行匹配(可能存在匹配失败的情况,若结果数组中的tag在消息包中找不到,则ength和valueOffset都为0)

(3) 消息包和结果数组中的tag值都按升序排列,且不重复

(4) 此消息包未被篡改,但尾部可能不完整,不完整的一组TLV请丢弃掉
输入描述

第一行:---个字符串,代表收到的消息包。字符串长度在10000以内。

说明1:字符串使用十六进制文本格式(字母为大写)来展示消息包的数据,如0F04ABABABAB代表一组TLV.前两个字符(0F)代表tag值为15,接下来两个字符(04)代表length值为4字节,接下来8个字符即为4字节的value。

说明2:输入字符串中,每一组TLV紧密排列,中间无空格等分隔符

第二行:需要匹配的tag数量n (0 <n <1000).

后面n行:需要匹配的n个tag值(十进制表示),递增排列。
输出描述

需要匹配的n个tag对应的n行匹配结果,每---行由长度和偏移量组成
示例1:
输入

0F04ABABABAB

1

15
输出

4 2
说明

tag15(十六进制0F)对应数据的长度为4,其value从第三个字节开始,因此偏移量为2
示例2:
输入

0F04ABABABAB1001FF

2

15

17
输出

4 2

0 0
说明

第二个tag匹配失败

思路

本题比较容易,但是细节分析比较繁琐,容易出错

新建一个TLV对象,含有3个属性tag,length以及offset。

遍历输入的第一行content,i的初始值为0。

第一个tag:content.subStr(i,i+2),利用Integer.parseInt将16进制字符串转为数字即可

第一个length: content.subStr(i+2,i+4)

第一个的offset为起始字符的索引/2:(i+4)/2

接下来的字符内容:content.subStr(i+4,i+4+2*length),也就是说下一个TLV对象的起始索引值为:i+4+2*length,

因为题目要求了"不完整的一组TLV请丢弃掉",即上述计算出来的tag或者length或者offset任意一个不存在,那么就不加入这个对象(只有当数组的索引越界时才会不存在)

接下来得到了两个排序的对象,list<TLV>以及nums

遍历nums,假设当前nums到 j 位置,list到 i 位置:

  1. 如果numsi>list.get(j).getTag():那么可以循环将j++,直到查找到下一个不大于numsi的位置,
  2. 如果list都遍历完了都没有找到,说明numsi大于list中的所有tag,此时直接将i位置的结果置为:0,0即可
  3. 如果循环后,numsi<list.get(j).getTag(),那么也说明找不到numsi,直接将i位置的结果置为:0,0
  4. 如果循环后,numsi==list.get(j).getTag(),说明找到了,此时直接将list.get(i)中存放的length以及offset返回即可

题解

java 复制代码
package hwod;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class TLVAnalyze {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String content = sc.nextLine();
        int n = sc.nextInt();
        int[] nums = new int[n];
        for (int i = 0; i < n; i++) {
            nums[i] = sc.nextInt();
        }
        int[][] res = tLVAnalyze(content, nums);
        for (int i = 0; i < res.length; i++) {
            System.out.println(res[i][0] + " " + res[i][1]);
        }
    }

    private static int[][] tLVAnalyze(String content, int[] nums) {
        int[][] res = new int[nums.length][2];
        List<TLV> list = new ArrayList<>();
        int i = 0;
        while (i < content.length()) {
            int tag = (i + 2) <= content.length() ? Integer.parseInt(content.substring(i, i + 2), 16) : -1;
            int length = (i + 4) <= content.length() ? Integer.parseInt(content.substring(i + 2, i + 4), 16) : -1;
            int offSet = i + 4 + 2 * length <= content.length() ? (i + 4) / 2 : -1;
            if (tag != -1 && length != -1 && offSet != -1) list.add(new TLV(tag, length, offSet));
            i = i + 4 + 2 * length;
        }
        i = 0;
        for (int j = 0; j < nums.length; j++) {
            int cur = nums[j];
            while (i < list.size() && cur > list.get(i).getTag()) {
                i++;
            }
            if (i >= list.size() || cur < list.get(i).getTag()) {
                res[j] = new int[]{0, 0};
            } else {
                res[j] = new int[]{list.get(i).getLength(), list.get(i).getOffSet()};
            }

        }
        return res;

    }
}

class TLV {
    private int tag;
    private int length;
    private int offSet;

    public int getTag() {
        return tag;
    }

    public int getLength() {
        return length;
    }

    public int getOffSet() {
        return offSet;
    }

    public TLV(int tag, int length, int offSet) {
        this.tag = tag;
        this.length = length;
        this.offSet = offSet;
    }
}

推荐

如果你对本系列的其他题目感兴趣,可以参考华为OD机试真题及题解(JAVA),查看当前专栏更新的所有题目。

相关推荐
namexingyun6 分钟前
开源前端生态如何成为 AI UI 生成的“燃料“:shadcn/ui、Tailwind CSS、Storybook 技术价值全解剖
java·前端·人工智能·python·ui·开源·ai编程
终将老去的穷苦程序员26 分钟前
基于SpringBoot的餐饮管理系统
java·spring boot·后端
心之伊始27 分钟前
Spring AI Tool Calling 实战:让 Java Agent 调用本地 Bean 工具方法
java·spring boot·agent·spring ai·tool calling
AI人工智能+电脑小能手32 分钟前
【大白话说Java面试题 第110题】【并发篇】第10题:CAS 存在哪些问题?
java·开发语言·面试
瀚高PG实验室1 小时前
java中间件无法连接数据库
java·数据库·中间件·瀚高数据库
东南门吹雪1 小时前
JAVA TCP socket编程框架
java·高并发·socket·tcp·nio
xingyuzhisuan1 小时前
缓存命中率提升方案:从 30% 优化至 82% 全流程优化记录
java·开发语言·缓存·ai
一条泥憨鱼1 小时前
Java开发效率神器:Lombok从入门到精通!
java·后端·学习·开发·lombok
Jinkxs1 小时前
Python基础 - 初识内置函数 Python自带的便捷工具
android·java·python
奥利奥夹心脆芙1 小时前
零基础调试 Java 代码:Gemini 报错排查完整实操指南
java