สมมติว่าเรามีรายการจำนวนเต็มที่แสดงข้อมูล เราต้องตรวจสอบว่าเข้ารหัส UTF-8 ถูกต้องหรือไม่ อักขระ UTF-8 หนึ่งตัวสามารถมีความยาวได้ 1 ถึง 4 ไบต์ มีคุณสมบัติบางอย่าง -
-
สำหรับอักขระ 1 ไบต์ บิตแรกคือ 0 ตามด้วยรหัสยูนิโค้ด
-
สำหรับอักขระ n-bytes n-bit แรกคือ 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 ดังนั้นค่านี้จะคืนค่าเป็นจริง เป็นการเข้ารหัสแบบ utf-8 ที่ถูกต้องสำหรับอักขระ 2 ไบต์ ตามด้วยอักขระ 1 ไบต์
เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -
-
cnt :=0
-
สำหรับฉันอยู่ในช่วง 0 ถึงขนาดของอาร์เรย์ข้อมูล
-
x :=data[i]
-
ถ้า cnt เป็น 0 แล้ว
-
ถ้า x/32 =110 ให้ตั้งค่า cnt เป็น 1
-
มิฉะนั้นเมื่อ x/16 =1110 แล้ว cnt =2
-
มิฉะนั้นเมื่อ x/8 =11110 แล้ว cnt =3
-
มิฉะนั้นเมื่อ x/128 เป็น 0 ให้คืนค่าเท็จ
-
-
มิฉะนั้นเมื่อ x /64 ไม่ใช่ 10 แล้วคืนค่าเท็จและลด cnt ลง 1
-
-
คืนค่า true เมื่อ cnt เป็น 0
ตัวอย่าง(C++)
ให้เราดูการใช้งานต่อไปนี้เพื่อความเข้าใจที่ดีขึ้น -
#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