题目描述
两端通过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
在消息包中找不到,则length
和valueOffset
都为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)