假设我们有一个表示数据的整数列表。我们必须检查它是否是有效的UTF-8编码。一个UTF-8字符可以是1到4字节长。有一些属性-
对于1字节字符,第一位为0,后跟其unicode码。
对于n字节字符,前n位全为1,n + 1位为0,其后为n-1个字节,其中最高有效2位为10。
所以编码技术如下-
字符数范围 | UTF-8字节序列 |
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 |
因此,如果输入类似于[197、130、1],则表示八位位组序列11000101 10000010 00000001,因此它将返回true。这是2字节字符后跟1字节字符的有效utf-8编码。
为了解决这个问题,我们将遵循以下步骤-
cnt:= 0
对于范围在0到数据数组大小的i
如果x / 32 = 110,则将cnt设置为1
否则,当x / 16 = 1110时,cnt = 2
否则,当x / 8 = 11110时,cnt = 3
否则,当x / 128为0时,返回false
x:=数据[i]
如果cnt为0,则
否则,当x / 64不为10时,返回false并将cnt减1
当cnt为0时返回true
让我们看下面的实现以更好地理解-
#include <bits/stdc++.h> using namespace std; class Solution { public: bool validUtf8(vector<int>& data) { int cnt = 0; for(int i = 0; i <data.size(); i++){ int x = data[i]; if(!cnt){ if((x >> 5) == 0b110){ cnt = 1; } else if((x >> 4) == 0b1110){ cnt = 2; } else if((x >> 3) == 0b11110){ cnt = 3; } else if((x >> 7) != 0) return false; } else { if((x >> 6) != 0b10) return false; cnt--; } } return cnt == 0; } }; main(){ Solution ob; vector<int> v = {197,130,1}; cout << (ob.validUtf8(v)); }
[197,130,1]
输出结果
1