【HUAWEI OJ 题库】编码格式校验

文章讲述了X-UTF编码规则,如何判断给定的十六进制字符串是否是合法的X-UTF编码,并计算字符的编号值。如果输入字符串符合规则,则返回编号,否则返回-1。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

假设X-UTF编码格式是一种变长字节编码方式,对于每个字符都有一个唯一编号值(如汉字“华”的编号值是21326)。每个字符按X-UTF编码后为n个字节(n 的范围为 [1,6] ),各字节需符合以下规则:

  • 单字节字符 (即 n = 1):字节的第一位(bit)为 0 。其余位为有效位。
  • 多字节字符 (即 n > 1):第一个字节的前 n 位都为 1,第 n+1 位为 0;后面字节的前两位都为 10。其余位为有效位。

二进制表示如下:

  • 1字节 0xxxxxxx
  • 2字节 110xxxxx 10xxxxxx
  • 3字节 1110xxxx 10xxxxxx 10xxxxxx
  • 4字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
  • 5字节 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
  • 6字节 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

其中 x 表示有效位,从首字节开始将所有字节的有效位依次拼接在一起,形成的有效数据的十进制值即为字符的编号值。
现给定一个十六进制表示的字符串,请判断是否是某字符的合法X-UTF编码:
若合法,返回该字符的编号值;
若不合法,则返回 -1 。
假设汉字 按X-UTF编码后为 E58D8E ,字节长度为 3,其有效数据的十进制值 21326,即为 的编号值。

解答要求

时间限制:1000ms, 内存限制:256MB

输入

一个十六进制表示的字符串,仅由字符0~9 和 A~F组成,每个长度范围为[2,12],且长度为偶数。

输出

一个整数,表示编号值,或 -1 。

样例

输入样例 1

E980A5

输出样例 1

36901

提示样例 1

E9 表示第一个字节,80 表示第二个字节,A5 表示第三个字节。
对应的二进制表示如下图,第一个字节的前 4 位为 1110,且后面两个字节的前两位都为 10,因此是合法编码; 其有效位拼接形成有效数据的示意如下:
在这里插入图片描述
输入样例 2

C0C0

输出样例 2

-1

提示样例 2

对应的二进制表示为 11000000 11000000,第二个字节不是 10 开头,所以不是合法编码,返回 -1 。

提示
在这里插入图片描述
编码实现(Java)

    public static void main(String[] args) {
        String strInput = "E980A5";
        int result = encodingVerify(strInput);
        System.out.println(result); // 输出: 36901
    }

    private static int encodingVerify(String strInput) {
        byte[] bytes = hexStringToByteArray(strInput);

        int n = bytes.length;
        int value = 0;

        // 首字节的前 n 位都为 1,第 n+1 位为 0,后面字节的前两位都为 10
        if ((bytes[0] & (0xFF << (8 - n))) == (0xFF << (8 - n)) && (bytes[1] & 0xC0) == 0x80) {
            value = bytes[0] & (0xFF >>> n);
            for (int i = 1; i < n; i++) {
                if ((bytes[i] & 0xC0) != 0x80) {
                    return -1; // 不符合规则,返回 -1
                }
                value = (value << 6) | (bytes[i] & 0x3F);
            }
            return value;
        }

        return -1; // 不符合规则,返回 -1
    }

    private static byte[] hexStringToByteArray(String hexString) {
        int len = hexString.length();
        byte[] data = new byte[len / 2];

        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
                    + Character.digit(hexString.charAt(i + 1), 16));
        }

        return data;
    }

输出结果

36901

Process finished with exit code 0
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值