Giả sử chúng ta có một danh sách các số nguyên đại diện cho dữ liệu. Chúng tôi phải kiểm tra xem nó có phải là mã hóa UTF-8 hợp lệ hay không. Một ký tự UTF-8 có thể dài từ 1 đến 4 byte. Có một số thuộc tính -
-
Đối với ký tự 1 byte, bit đầu tiên là 0, tiếp theo là mã unicode của nó.
-
Đối với ký tự n-byte, n-bit đầu tiên đều là 1s, n + 1 bit là 0, tiếp theo là n-1 byte với 2 bit quan trọng nhất là 10.
Vì vậy, kỹ thuật mã hóa như sau -
Phạm vi số ký tự | Chuỗi bát phân 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 |
Vì vậy, nếu đầu vào là [197, 130, 1], điều này đại diện cho chuỗi octet 11000101 10000010 00000001, vì vậy giá trị này sẽ trả về true. Đây là mã hóa utf-8 hợp lệ cho ký tự 2 byte theo sau là ký tự 1 byte.
Để giải quyết vấn đề này, chúng tôi sẽ làm theo các bước sau -
-
cnt:=0
-
cho tôi trong phạm vi từ 0 đến kích thước của mảng dữ liệu
-
x:=data [i]
-
nếu cnt là 0 thì
-
nếu x / 32 =110, thì đặt cnt là 1
-
ngược lại khi x / 16 =1110 thì cnt =2
-
ngược lại khi x / 8 =11110 thì cnt =3
-
ngược lại khi x / 128 bằng 0 thì trả về false
-
-
ngược lại khi x / 64 không phải là 10, thì trả về false và giảm cnt đi 1
-
-
trả về true khi cnt bằng 0
Ví dụ (C ++)
Hãy cùng chúng tôi xem cách triển khai sau để hiểu rõ hơn -
#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)); }
Đầu vào
[197,130,1]
Đầu ra
1