สมมติว่าเรามีรายการจำนวนเต็มที่แสดงข้อมูล เราต้องตรวจสอบว่าเข้ารหัส 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