데이터를 나타내는 정수 목록이 있다고 가정합니다. 유효한 UTF-8 인코딩인지 여부를 확인해야 합니다. 하나의 UTF-8 문자는 1~4바이트 길이가 될 수 있습니다. 몇 가지 속성이 있습니다 -
-
1바이트 문자의 경우 첫 번째 비트는 0이고 그 뒤에 유니코드 코드가 옵니다.
-
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 :=데이터[i]
-
cnt가 0이면
-
x/32 =110이면 cnt를 1로 설정
-
그렇지 않으면 x/16 =1110일 때 cnt =2
-
그렇지 않으면 x/8 =11110일 때 cnt =3
-
그렇지 않으면 x/128이 0이면 false를 반환합니다.
-
-
그렇지 않으면 x /64가 10이 아닌 경우 false를 반환하고 cnt를 1로 줄입니다.
-
-
cnt가 0일 때 true를 반환
예시(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