华为OD机考算法题:TLV解码

目录

题目部分

解析与思路

代码实现


题目部分

题目 TLV编码
题目说明 TLV编码是按[Tag Length Value]格式进行编码的,一段码流中的信元用Tag标识,Tag在码流中唯一不重复,Length表示信元Value的长度,Value表示信元的值。
码流以某信元的Tag开头,Tag固定占一个字节,Length固定占两个字节,字节序为小端序。
现给定TLV格式编码的码流,以及需要解码的信元Tag,请输出该信元的Value。
输入码流的16机制字符中,不包括小写字母,且要求输出的16进制字符串中也不要包含小写字母;码流字符串的最大长度不超过50000个字节。
输入描述 输入的第一行为一个字符串,表示待解码信元的Tag;
输入的第二行为一个字符串,表示待解码的16进制码流,字节之间用空格分隔。
输出描述 输出一个字符串,表示待解码信元以16进制表示的Value。
补充说明

---------------------------------------------------------------------------------------

示例
示例1
输入 31
32 01 00 AE 90 02 00 01 02 30 03 00 AB 32 31 31 02 00 32 33 33 01 00 CC
输出 32 33
说明 需要解析的信元的Tag是31,从码流的起始处开始匹配,Tag为32的信元长度为1(01 00,小端序表示为1);
第二个信元的Tag是90,其长度为2;
第三个信元的Tag是30,其长度为3;
第四个信元的Tag是31,其长度为2(02 00),所以返回长度后面的两个字节即可,即32 33。

解析与思路

题目解读

题目中,输入的第二行是TLV信息流。TLV信息流由多个信元组成,而每个信元由Tag、Length、Value组成;输入第一行是Tag,即需要从第二行数据流中输出信元 Value 所对应的 Tag。

题目要求从第二行的多个信元中,找到第一行的Tag所对应的信元。然后输出此信元的Value。

在输入示例中,第一行指定了信元的Tag是31,第二行输入的信息流包含了5个信元,依次为32、90、30、31、33。我们找到Tag为31的信元,它为 31 02 00 32 33,其中 31 是Tag,02 00(即2)是长度,那么其紧跟的2个字节 32 33 为Value,所以最终的结果输出为 32 33。

分析与思路

此题根据指定的tag,从信息流中找到对应的信息员,输出其value即可,并不涉及太复杂的逻辑算法。实现如下:

1. 记录第一行输入的数字,设为变量 tag。
2. 逐一遍历第二行输入的信息流。遍历时,先判断第一个输入是否等于tag:

  • 如果等于 tag,则继续遍历接下来的2个字节,(根据小端序)计算长度,设为变量 length,然后输出接下来的 length 个字节,即为最终输出。输出后退出程序。
  • 如果不等于tag,则继续遍历接下来的2个字节,计算长度,设为变量length,然后跳过接下来的 length 个字节,然后继续步骤 2。

此算法只需要遍历一次第二行的输入,时间复杂度为O(n),只需要2个额外的辅助变量,空间复杂度为O(1)。


代码实现

Java代码

import java.util.Scanner;

/**
 * TLV解码
 * @since 2023.09.04
 * @version 0.1
 * @author Frank
 *
 */
public class LTV_Solution {

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

		// 第一行输入的tag
		String tag = sc.nextLine();
		// 第二行输入的TLV数据流
		String stream = sc.nextLine();
		String[] input = stream.split(" ");

		int i = 0;
		while (i < input.length) {
			String tagTmp = input[i];

			String lengthStr = input[i + 2] + input[i + 1];
			int length = Integer.parseInt(lengthStr, 16);

			// 已找到,输出
			if ( !tagTmp.equals( tag )) {
				// 没有找到Tag,略过,寻找下一个
				i += ( 3 + length);
				continue;
			}
			StringBuilder outputSB = new StringBuilder();
			for (int j = 0; j < length; j++) {
				outputSB.append(input[i + j + 3]);
				if (j != length - 1) {
					outputSB.append(" ");
				}
			}
			System.out.println(outputSB.toString());
			return;
		}

	}

}

JavaScript代码

const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;
void async function() {
    // write your code here
    let input = [];
    while (line = await readline()) {
        input.push(line);
    }

    // 第一行数据
    var tag = input[0];
    // 第二行数据转换成数组
    var ltvs = input[1].split(" ");

    var i = 0;
    while (i < ltvs.length) {
        var tagTmp = ltvs[i];
        var lengthStr = ltvs[i + 2] + ltvs[i + 1];
        var length = parseInt(lengthStr, 16);

        // 已找到,输出
        if (tagTmp != tag ) {
            // 没有找到Tag,略过,寻找下一个
            i += (3 + length);
            continue;
        }
        var output = "";
        for (var j = 0; j < length; j++) {
            output += ( ltvs[i + j + 3]);
            if (j != length - 1) {
                output += " ";
            }
        }
        console.log( output );
        return;
    }

}();

(完)

你可能感兴趣的:(华为OD机考,华为OD,机考,算法,数据结构,Java,JavaScript)