2023华为OD机试 (B卷)|200分 TLV格式(Java JavaScript C++ Python)

题目描述

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

  • (1)消息包中多组tag,length,value紧密排列,其中tag,length各种1字节(uint8_t),value所占字节数等于length的值。
  • (2)结果数组中tag值已知,需要田中每个tag对应数据的length和valueOffset值(valueOffset为value在原消息包中的起始偏移量(从0开始,以字节为单位)),即将消息包中的tag与结果数组中的tag进行匹配(可能存在匹配失败的情况,若结果数组中tag在消息包中找不到,则lengthvalueOffset都为0)
  • (3)消息包和结果数组职工的tag值都按升序排序,且不重复。
  • (4) 此消息包未被篡改,但尾部可能不完整,不完整的一组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行匹配结果,每一行由长度和偏移量组成.

用例

输入0F04ABABABAB
1
15
输出4 2
说明tag15(十六进制0F)对应数据的长度为4,其value从第三个字节开始,因此偏移量为2
输入0F04ABABABAB1001FF
2
15
17
输出4 2
0 0
说明第二个tag匹配失败

Java

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // 定义变量并读取输入
        String msg = scanner.next();
        int n = scanner.nextInt();

        int[] tags = new int[n];
        for (int i = 0; i < n; i++) {
            tags[i] = scanner.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.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");
            }
        }
    }
}

JavaScript

const readline = require("readline");
 
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});
 
const lines = [];
let msg;
let n;
rl.on("line", (line) => {
  lines.push(line);
 
  if (lines.length === 2) {
    msg = lines[0];
    n = lines[1] - 0;
  }
 
  if (n && lines.length === n + 2) {
    const tags = lines.slice(2).map(Number);
    const tagObj = {};
 
    for (let i = 0; i + 3 < msg.length; i++) {
      const tag = parseInt(msg.slice(i, i + 2), 16);
      const len = parseInt(msg.slice(i + 2, i + 4), 16);
      const valueOffset = Math.floor((i + 5) / 2);
 
      i = i + 3 + len * 2;
 
      if (i >= msg.length) break;
 
      tagObj[tag] = [len, valueOffset];
    }
 
    tags.forEach((tag) => {
      if (tagObj[tag]) {
        const [len, valueOffset] = tagObj[tag];
        console.log(`${len} ${valueOffset}`);
      } else {
        console.log("0 0");
      }
    });
 
    lines.length = 0;
  }
});

C++

#include <iostream>
#include <unordered_map>
#include <string>
#include <sstream>
#include <vector>

using namespace std;

int main() {
    // 定义变量并读取输入
    string msg;
    int n;
    cin >> msg >> n;

    int tags[n];
    for (int i = 0; i < n; i++) {
        cin >> tags[i];
    }

    // 定义哈希表,存储tag对应的length和valueOffset
    unordered_map<int, vector<int>> tagMap;

    // 解析msg,填充哈希表
    for (int i = 0; i + 3 < msg.length(); i++) {
        int tag, len, valueOffset;
        string tagStr = msg.substr(i, 2);
        string lenStr = msg.substr(i + 2, 2);

        // 将16进制字符串转换为整数
        stringstream ss;
        ss << hex << tagStr;
        ss >> tag;

        ss.clear();
        ss << hex << lenStr;
        ss >> len;

        // 计算valueOffset
        valueOffset = (i + 5) / 2;

        // 跳过value,更新i
        i += 3 + len * 2;

        // 如果i超出msg长度,跳出循环
        if (i >= msg.length()) break;

        // 将tag、length、valueOffset存入哈希表中
        tagMap[tag] = {len, valueOffset};
    }

    // 遍历tags,输出匹配结果
    for (int tag : tags) {
        if (tagMap.count(tag)) {
            vector<int> tmp = tagMap[tag];
            int len = tmp[0];
            int valueOffset = tmp[1];
            cout << len << " " << valueOffset << endl;
        } else {
            cout << "0 0" << endl;
        }
    }

    return 0;
}

Python

# 导入必要的库
from collections import defaultdict

# 定义变量并读取输入
msg = input()
n = int(input())

tags = []
for i in range(n):
    tags.append(int(input()))

# 定义哈希表,存储tag对应的length和valueOffset
tagMap = defaultdict(list)

# 解析msg,填充哈希表
for i in range(len(msg) - 3):
    tagStr = msg[i:i+2]
    lenStr = msg[i+2:i+4]

    # 将16进制字符串转换为整数
    tag = int(tagStr, 16)
    length = int(lenStr, 16)

    # 计算valueOffset
    valueOffset = (i + 5) // 2

    # 跳过value,更新i
    i += 3 + length * 2

    # 如果i超出msg长度,跳出循环
    if i >= len(msg):
        break

    # 将tag、length、valueOffset存入哈希表中
    tagMap[tag] = [length, valueOffset]

# 遍历tags,输出匹配结果
for tag in tags:
    if tag in tagMap:
        tmp = tagMap[tag]
        length = tmp[0]
        valueOffset = tmp[1]
        print(length, valueOffset)
    else:
        print(0, 0)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值