[R54B]身份证号
对于 的数据,,且 中只包含大写字母、小写字母和数字。
思路
题目要求按身份证号规则逐项校验字符串 :长度恰好为 ;前两个字符是 A 到 G 之间的大写字母;第 到第 个字符是数字 ;最后一个字符是数字或大写字母 X。
由于 中只含 ASCII 字符(字母与数字),可以按字节逐位判断。按规则顺序设置四道关卡,任意一道不满足即输出 No 并提前结束,全部通过才输出 Yes:
- 长度校验:若 ,直接
No。 - 前缀校验: 和 的字节值应落在
A到G的范围()。 - 数字段校验: 五个字节应落在
0到9的范围()。 - 末位校验: 应是数字,或等于大写字母
X()。
复杂度
- 时间复杂度:,至多扫描 个字节。
- 空间复杂度:,存储输入字符串。
仓颉实现
import std.env.*
main(): Int64 {
let reader = getStdIn()
let s = reader.readln().getOrThrow()
if (s.size != 8) {
println("No")
return 0
}
// s[0], s[1] in 'A'..'G' (65..71)
if (s[0] < UInt8(65) || s[0] > UInt8(71) || s[1] < UInt8(65) || s[1] > UInt8(71)) {
println("No")
return 0
}
// s[2..6] digits '0'..'9' (48..57)
var i = 2
while (i <= 6) {
if (s[i] < UInt8(48) || s[i] > UInt8(57)) {
println("No")
return 0
}
i += 1
}
// s[7] digit or 'X' (88)
let last = s[7]
if ((last >= UInt8(48) && last <= UInt8(57)) || last == UInt8(88)) {
println("Yes")
} else {
println("No")
}
return 0
}