SG12. UTF-8编码验证
描述
UTF-8 中的一个字符可能的长度为 1 到 4 字节,遵循以下的规则:
1. 对于 1 字节的字符,字节的第一位设为0,后面7位为这个符号的unicode码。
2. 对于 n 字节的字符 (n > 1),第一个字节的前 n 位都设为1,第 n+1 位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。
这个是UTF-8编码的工作方式:
Char. number range | UTF-8 octet sequence (hexadecimal) | (binary) --------------------+--------------------------------------------- 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给定一个表示数据的整数数组,返回它是否为有效的 utf-8 编码。
输入描述
多行字符串,每行字符串包括整数数字以及数字之间分隔符英文逗号(,)。每个整数只有最低8个有效位来存储数据,这就意味着每个整数只表示一个字节的数据。输出描述
对输入的每行数据均进行验证,并输出true或者false。true代表有效的utf-8编码,false则是无效的。示例1
输入:
197,130,1
输出:
true
说明:
data = [197, 130, 1], 表示 8 位的序列: 11000101 10000010 00000001.示例2
输入:
235,140,4
输出:
false
说明:
data = [235, 140, 4], 表示 8 位的序列: 11101011 10001100 00000100.C++ 解法, 执行用时: 2ms, 内存消耗: 404KB, 提交时间: 2020-10-31
#include <bits/stdc++.h> using namespace std; int getLine(string& res) { int ans = 0, in = 0; for (;;) { int c = getchar(); if (isgraph(c)) { res.push_back((char)c); in = 1; ans++; } else if (c == EOF || in) { break; } } return ans; } void trans(string& input, vector<int>& res) { for (int i = 0, cur = 0, s = input.size(); i <= input.size(); ++i) { if (i == s || !isdigit(input[i])) { res.push_back(cur); cur = 0; } else { cur = 10 * cur + input[i] - '0'; } } } int leadingOne(int x) { int ans = 0; for (int i = 7; i >= 0; --i) { if ((1 << i) & x) { ans++; } else { break; } } return ans; } bool solve(const vector<int>& nums) { for (int i = 0, s = nums.size(); i < s; ++i) { int n = leadingOne(nums[i]); if (n > 4 || n == 1) { return false; } else if (n) { if (s - i < n) return false; for (int j = 1; j < n; ++j) { if (leadingOne(nums[i + j]) != 1) return false; } i += n - 1; } } return true; } int main() { for (string line; getLine(line); line.clear()) { vector<int> nums; trans(line, nums); puts(solve(nums) ? "true" : "false"); } return 0; }
C++ 解法, 执行用时: 2ms, 内存消耗: 500KB, 提交时间: 2020-10-31
#include <bits/stdc++.h> using namespace std; int getLine(string& res) { int ans = 0, in = 0; for (;;) { int c = getchar(); if (isgraph(c)) { res.push_back((char)c); in = 1; ans++; } else if (c == EOF || in) { break; } } return ans; } void trans(string& input, vector<int>& res) { for (int i = 0, cur = 0, s = input.size(); i <= input.size(); ++i) { if (i == s || !isdigit(input[i])) { res.push_back(cur); cur = 0; } else { cur = 10 * cur + input[i] - '0'; } } } int leadingOne(int x) { int ans = 0; for (int i = 7; i >= 0; --i) { if ((1 << i) & x) { ans++; } else { break; } } return ans; } bool solve(const vector<int>& nums) { for (int i = 0, s = nums.size(); i < s; ++i) { int n = leadingOne(nums[i]); if (n > 4 || n == 1) { return false; } else if (n) { if (s - i < n) return false; for (int j = 1; j < n; ++j) { if (leadingOne(nums[i + j]) != 1) return false; } i += n - 1; } } return true; } int main() { for (string line; getLine(line); line.clear()) { vector<int> nums; trans(line, nums); puts(solve(nums) ? "true" : "false"); } return 0; }
C++ 解法, 执行用时: 3ms, 内存消耗: 376KB, 提交时间: 2020-11-01
#include <bits/stdc++.h> using namespace std; int getLine(string& res) { int ans = 0, in = 0; for (;;) { int c = getchar(); if (isgraph(c)) { res.push_back((char)c); in = 1; ans++; } else if (c == EOF || in) { break; } } return ans; } void trans(string& input, vector<int>& res) { for (int i = 0, cur = 0, s = input.size(); i <= input.size(); ++i) { if (i == s || !isdigit(input[i])) { res.push_back(cur); cur = 0; } else { cur = 10 * cur + input[i] - '0'; } } } int leadingOne(int x) { int ans = 0; for (int i = 7; i >= 0; --i) { if ((1 << i) & x) { ans++; } else { break; } } return ans; } bool solve(const vector<int>& nums) { for (int i = 0, s = nums.size(); i < s; ++i) { int n = leadingOne(nums[i]); if (n > 4 || n == 1) { return false; } else if (n) { if (s - i < n) return false; for (int j = 1; j < n; ++j) { if (leadingOne(nums[i + j]) != 1) return false; } i += n - 1; } } return true; } int main() { for (string line; getLine(line); line.clear()) { vector<int> nums; trans(line, nums); puts(solve(nums) ? "true" : "false"); } return 0; }
C++ 解法, 执行用时: 3ms, 内存消耗: 480KB, 提交时间: 2020-05-31
#include<iostream> #include<string> #include<vector> using namespace std; void addressString(std::string& line,std::vector<int>& data){ int cnt=0; for(int i=0;i<line.size();++i){ if(line[i]!=',') cnt = cnt*10+line[i]-'0'; else{ if(cnt>255) cnt = cnt%255; data.push_back(cnt); cnt = 0; } } if(cnt>255) cnt = cnt%255; data.push_back(cnt); return ; } bool adressData(std::vector<int>&data){ int start = 0; while(start<data.size()){ if(data[start]<=127) start +=1; else{ int count = 0; int cp=128; int current = data[start]; while(current>=cp&&cp>=1){ count+=1; current -=cp; cp = cp/2; } if((count==1) || count>4) return false; int end = start+count-1; if(end>=data.size()) return false; start +=1; while(start<=end){ if(data[start]<128||data[start]>=192) return false; start +=1; } } } return true; } int main(){ std::string line=""; while(std::cin>>line){ std::vector<int> data; addressString(line,data); if(adressData(data)) std::cout<<"true"<<std::endl; else std::cout<<"false"<<std::endl; } return 0; }
C++ 解法, 执行用时: 3ms, 内存消耗: 484KB, 提交时间: 2020-05-20
#include <bits/stdc++.h> using namespace std; int getLine(string& res) { int ans = 0, in = 0; for (;;) { int c = getchar(); if (isgraph(c)) { res.push_back((char)c); in = 1; ans++; } else if (c == EOF || in) { break; } } return ans; } void trans(string& input, vector<int>& res) { for (int i = 0, cur = 0, s = input.size(); i <= input.size(); ++i) { if (i == s || !isdigit(input[i])) { res.push_back(cur); cur = 0; } else { cur = 10 * cur + input[i] - '0'; } } } int leadingOne(int x) { int ans = 0; for (int i = 7; i >= 0; --i) { if ((1 << i) & x) { ans++; } else { break; } } return ans; } bool solve(const vector<int>& nums) { for (int i = 0, s = nums.size(); i < s; ++i) { int n = leadingOne(nums[i]); if (n > 4 || n == 1) { return false; } else if (n) { if (s - i < n) return false; for (int j = 1; j < n; ++j) { if (leadingOne(nums[i + j]) != 1) return false; } i += n - 1; } } return true; } int main() { for (string line; getLine(line); line.clear()) { vector<int> nums; trans(line, nums); puts(solve(nums) ? "true" : "false"); } return 0; }