列表

详情


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 个有效位用来存储数据。这意味着每个整数只表示 1 字节的数据。



输入描述

多行字符串,每行字符串包括整数数字以及数字之间分隔符英文逗号(,)。每个整数只有最低8个有效位来存储数据,这就意味着每个整数只表示一个字节的数据。

输出描述

对输入的每行数据均进行验证,并输出true或者false。true代表有效的utf-8编码,false则是无效的。

示例1

输入:

197,130,1

输出:

true

说明:

data = [197, 130, 1], 表示 8 位的序列: 11000101 10000010 00000001.
返回 true 。
这是有效的 utf-8 编码,为一个2字节字符,跟着一个1字节字符。

示例2

输入:

235,140,4

输出:

false

说明:

data = [235, 140, 4], 表示 8 位的序列: 11101011 10001100 00000100.
返回 false 。
前 3 位都是 1 ,第 4 位为 0 表示它是一个3字节字符。
下一个字节是开头为 10 的延续字节,这是正确的。
但第二个延续字节不以 10 开头,所以是不符合规则的。

原站题解

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;
}

上一题