牛客题解 | UTF-8 编码验证
1.牛客题解 | 5-血型遗传检测2.牛客题解 | 61-递归和动态规划-汉诺塔II3.牛客题解 | Anniversary4.牛客题解 | BST判定5.牛客题解 | CCNumber6.牛客题解 | CIDR去重7.牛客题解 | DNA序列8.牛客题解 | D塔29.牛客题解 | Fibonacci数列10.牛客题解 | K 的倍数11.牛客题解 | Kolakoski 序列12.牛客题解 | LRU Cache13.牛客题解 | LUCKY STRING14.牛客题解 | N-GCD15.牛客题解 | Numeric Keypad16.牛客题解 | Shopee的办公室(二)17.牛客题解 | Spring Outing
18.牛客题解 | UTF-8 编码验证
19.牛客题解 | Unix路径简化20.牛客题解 | bit count21.牛客题解 | bit位数22.牛客题解 | filename extension23.牛客题解 | geohash编码24.牛客题解 | ipv4地址白名单25.牛客题解 | ipv4地址白名单_126.牛客题解 | k倍多重正整数集合27.牛客题解 | n个数里出现次数大于等于n除以2的数28.牛客题解 | n个数里最小的k个29.牛客题解 | water30.牛客题解 | xor31.牛客题解 | ん...红茶?32.牛客题解 | 一封奇怪的信33.牛客题解 | 一组带数字编号的球,其中有两个编号只出现了一次,把它们找出来34.牛客题解 | 万万没想到之抓捕孔连顺35.牛客题解 | 万万没想到之聪明的编辑36.牛客题解 | 上台阶37.牛客题解 | 上高楼38.牛客题解 | 下厨房39.牛客题解 | 不想出差的HR40.牛客题解 | 不要二41.牛客题解 | 丢失的三个数42.牛客题解 | 两两配对差值最小43.牛客题解 | 两个子串44.牛客题解 | 两个整数二进制位不同个数45.牛客题解 | 两种排序方法46.牛客题解 | 中位数47.牛客题解 | 中缀表达式转后缀表达式48.牛客题解 | 丰收49.牛客题解 | 串的模式匹配50.牛客题解 | 之字形打印矩阵51.牛客题解 | 乔乔的包52.牛客题解 | 乘坐公交53.牛客题解 | 乘方取模54.牛客题解 | 买房55.牛客题解 | 买橘子56.牛客题解 | 买苹果57.牛客题解 | 买面包58.牛客题解 | 争吵59.牛客题解 | 二分图判定60.牛客题解 | 二分图判定_161.牛客题解 | 二分查找62.牛客题解 | 二叉搜索树判定63.牛客题解 | 二叉树的序列化64.牛客题解 | 二维数组打印65.牛客题解 | 二进制中有多少个166.牛客题解 | 交叉线67.牛客题解 | 交换查询68.牛客题解 | 交错01串69.牛客题解 | 交错序列70.牛客题解 | 代价71.牛客题解 | 任务调度72.牛客题解 | 优雅的点73.牛客题解 | 会话列表74.牛客题解 | 会话列表_175.牛客题解 | 伪正则表达式76.牛客题解 | 俄罗斯方块77.牛客题解 | 保卫方案78.牛客题解 | 保留最大的数79.牛客题解 | 信用卡推荐客户列表80.牛客题解 | 倒水81.牛客题解 | 倒着输出整数82.牛客题解 | 倒置字符串83.牛客题解 | 公交车84.牛客题解 | 公平划分85.牛客题解 | 公约数86.牛客题解 | 六一儿童节87.牛客题解 | 共享单车88.牛客题解 | 关灯游戏89.牛客题解 | 冒泡排序90.牛客题解 | 写一段程序判断IP字符串是否属于内网IP题目
解题思路
验证 编码的有效性,需要按照以下规则检查:
-
字节长度规则:
- 1字节:首位为0
- 2字节:首字节以110开头,后续1个字节以10开头
- 3字节:首字节以1110开头,后续2个字节以10开头
- 4字节:首字节以11110开头,后续3个字节以10开头
-
检查步骤:
- 检查首字节确定字符长度
- 验证后续字节是否都以10开头
- 确保数组长度足够包含完整字符
代码
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
class Solution {
public:
bool validUtf8(vector<int>& data) {
int n = data.size();
int i = 0;
while (i < n) {
int bytes = getCharLength(data[i]);
if (bytes == 0) return false;
// 检查是否有足够的后续字节
if (i + bytes > n) return false;
// 验证后续字节
for (int j = 1; j < bytes; j++) {
if (!isValidContinuation(data[i + j])) {
return false;
}
}
i += bytes;
}
return true;
}
private:
int getCharLength(int byte) {
if ((byte & 0x80) == 0) return 1;
else if ((byte & 0xE0) == 0xC0) return 2;
else if ((byte & 0xF0) == 0xE0) return 3;
else if ((byte & 0xF8) == 0xF0) return 4;
return 0; // 无效的首字节
}
bool isValidContinuation(int byte) {
return (byte & 0xC0) == 0x80;
}
};
int main() {
string line;
while (getline(cin, line)) {
vector<int> data;
stringstream ss(line);
string num;
while (getline(ss, num, ',')) {
data.push_back(stoi(num));
}
Solution solution;
cout << (solution.validUtf8(data) ? "true" : "false") << endl;
}
return 0;
}
import java.util.*;
public class Main {
static class Solution {
public boolean validUtf8(int[] data) {
int n = data.length;
int i = 0;
while (i < n) {
int bytes = getCharLength(data[i]);
if (bytes == 0) return false;
// 检查是否有足够的后续字节
if (i + bytes > n) return false;
// 验证后续字节
for (int j = 1; j < bytes; j++) {
if (!isValidContinuation(data[i + j])) {
return false;
}
}
i += bytes;
}
return true;
}
private int getCharLength(int byte1) {
if ((byte1 & 0x80) == 0) return 1;
else if ((byte1 & 0xE0) == 0xC0) return 2;
else if ((byte1 & 0xF0) == 0xE0) return 3;
else if ((byte1 & 0xF8) == 0xF0) return 4;
return 0; // 无效的首字节
}
private boolean isValidContinuation(int byte1) {
return (byte1 & 0xC0) == 0x80;
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNextLine()) {
String[] nums = sc.nextLine().split(",");
int[] data = new int[nums.length];
for (int i = 0; i < nums.length; i++) {
data[i] = Integer.parseInt(nums[i]);
}
Solution solution = new Solution();
System.out.println(solution.validUtf8(data) ? "true" : "false");
}
}
}
def get_char_length(byte: int) -> int:
"""获取UTF-8字符的字节长度"""
if (byte & 0x80) == 0:
return 1
elif (byte & 0xE0) == 0xC0:
return 2
elif (byte & 0xF0) == 0xE0:
return 3
elif (byte & 0xF8) == 0xF0:
return 4
return 0 # 无效的首字节
def is_valid_continuation(byte: int) -> bool:
"""检查是否是有效的后续字节"""
return (byte & 0xC0) == 0x80
def valid_utf8(data: list) -> bool:
"""验证UTF-8编码的有效性"""
n = len(data)
i = 0
while i < n:
bytes_len = get_char_length(data[i])
if bytes_len == 0:
return False
# 检查是否有足够的后续字节
if i + bytes_len > n:
return False
# 验证后续字节
for j in range(1, bytes_len):
if not is_valid_continuation(data[i + j]):
return False
i += bytes_len
return True
if __name__ == "__main__":
while True:
try:
data = list(map(int, input().split(',')))
print("true" if valid_utf8(data) else "false")
except EOFError:
break
算法及复杂度
- 算法:位运算 + 模拟
- 时间复杂度:,其中 为数组长度
- 空间复杂度:,只使用常数额外空间
合集:
牛客笔试大厂真题题解1
分类:
牛客笔试大厂真题题解1
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理