LeetCode 393. UTF-8 编码验证题解

393. UTF-8 编码验证题解

题目来源:393. UTF-8 编码验证

2022.03.13 每日一题

LeetCode 题解持续更新中Github仓库地址 CSDN博客地址

不知道是不是我阅读能力下降了太多了,今天的题目最初都没太看明白,看了好久才看懂

在这里偷偷放一个链接传送门,我自己认为这个把 UTF-8 和 Unicode 的转换讲的很清晰

最后我看明白了这道题目,就是让你把数组中的数字转换成为二进制,然后匹配对应的 Unicode 的编码方式,判断其是否是合法的。

那就比较容易了,模拟就好

Char number range | UTF-8 octet sequence
(hexadecimal) | (binary)
----------------------------±--------------------------------------------
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

我们可以导出 这些二进制数组转换成为十进制数字的大小,用大小来圈定范围

class Solution {
public:
    bool validUtf8(vector<int> &data) {
        // 统计字符串的长度,后续进行遍历数组
        int len = data.size();
        for (int i = 0; i < len; i++) {
            // 此条件满足第一种情况   0000 0000-0000 007F | 0xxxxxxx
            if (data[i] < 128) continue;
            // 所给的最大值是 0010FFFF 十进制就是 247
            // 因此如果出现了大于 427 的数字就说明这个不可能是 Unicode 的编码
            if (data[i] > 247) return false;
            
            // 这里判断第二组 0000 0080-0000 07FF | 110xxxxx 10xxxxxx
            if (data[i] > 191 && data[i] < 224) {
                // 判断 当前索引的位置,如果当前索引的位置不够后续所需的空间的剩余,直接返回 false 就行
                if (i >= len - 1) return false;
                // 到这里满足了 Unicode 码的数量,判断后续是否满足条件
                if (data[i + 1] > 127 && data[i + 1] < 192) {
                    // 如果满足了,就跳过
                    i++;
                    continue;
                }
                // 否则就返回 false
                return false;
            }

            // 原理同上
            if (data[i] > 223 && data[i] < 240) {
                if (i >= len - 2) return false;
                for (int j = 1; j <= 2; j++) {
                    if (!(data[i + j] > 127 && data[i + j] < 192)) {
                        return false;
                    }
                }
                i += 2;
                continue;
            }

            if (data[i] > 239 && data[i] < 249) {
                if (i >= len - 3) return false;
                for (int j = 1; j <= 3; j++) {
                    if (!(data[i + j] > 127 && data[i + j] < 192)) {
                        return false;
                    }
                }
                i += 3;
                continue;
            }
            // 如果数字不在上述范围,就直接返回 false 就行
            // 真的不能删,面向答案编程总结出来的惨痛教训,会有一部分数字在上述范围之外
            return false;
        }
        // 满足上述的所有条件,安全到达这里,返回 true!
        return true;
    }
};
class Solution {
    public boolean validUtf8(int[] data) {
        // 统计字符串的长度,后续进行遍历数组
        int len = data.length;
        for (int i = 0; i < len; i++) {
            // 此条件满足第一种情况   0000 0000-0000 007F | 0xxxxxxx
            if (data[i] < 128) continue;
            // 所给的最大值是 0010FFFF 十进制就是 247
            // 因此如果出现了大于 427 的数字就说明这个不可能是 Unicode 的编码
            if (data[i] > 247) return false;

            // 这里判断第二组 0000 0080-0000 07FF | 110xxxxx 10xxxxxx
            if (data[i] > 191 && data[i] < 224) {
                // 判断 当前索引的位置,如果当前索引的位置不够后续所需的空间的剩余,直接返回 false 就行
                if (i >= len - 1) return false;
                // 到这里满足了 Unicode 码的数量,判断后续是否满足条件
                if (data[i + 1] > 127 && data[i + 1] < 192) {
                    // 如果满足了,就跳过
                    i++;
                    continue;
                }
                // 否则就返回 false
                return false;
            }

            // 原理同上
            if (data[i] > 223 && data[i] < 240) {
                if (i >= len - 2) return false;
                for (int j = 1; j <= 2; j++) {
                    if (!(data[i + j] > 127 && data[i + j] < 192)) {
                        return false;
                    }
                }
                i += 2;
                continue;
            }

            if (data[i] > 239 && data[i] < 249) {
                if (i >= len - 3) return false;
                for (int j = 1; j <= 3; j++) {
                    if (!(data[i + j] > 127 && data[i + j] < 192)) {
                        return false;
                    }
                }
                i += 3;
                continue;
            }
            // 如果数字不在上述范围,就直接返回 false 就行
            // 真的不能删,面向答案编程总结出来的惨痛教训,会有一部分数字在上述范围之外
            return false;
        }
        // 满足上述的所有条件,安全到达这里,返回 true!
        return true;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值