PTA | 程序设计类实验辅助教学平台 (pintia.cn)
解析
加权
首先要知道什么叫做加权:
加权求和实际上就是身份证的每一位乘以权重再相加。
因为输入的身份证包含字符'x',所以要用字符型数组,我们用s表示。(包含'x'是一种非法情况)
那么我们就枚举身份证的每一位s[i],s[i]去乘对应的每一位权值w[j],我们需要把所有的权值都列出来,通过下标去遍历:
int w[18] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
每个都会得到一个乘积,我们把这个乘积分别, 都会得到一个值,z值可以去校验表里找:
题目给了我们张z表(z表包含了z值的所有可能)。z表与校验表之间存在映射关系,我们发现z表就是校验表的下标映射:
char jiaoyan[11] = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
Z:0 1 2 3 4 5 6 7 8 9 10
我们在校验表里通过z值下标找到对应的 校验码,拿这个校验码 去和身份证码的最后一位校验码 做比较 , 如果一致, 那么就是合法身份证 。
最后我们用 flag 做一下标记,在循环当中每输出一个不合法身份证 就 flag++,到最后循环结束,如果 falg 为0,就说明全是合法身份证,那我们就输出 “All passed ”
code
#include <iostream>
using namespace std;
int main(){
int n, z, i, flag = 0;
string s;
//建立权重的映射,因为我们要拿身份证每一位乘每一位对应的权值。所以权值要全部列出来
int w[18] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
//我们最后得到的z要在校验表里找到 对应的校验值
char jiaoyan[11] = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
cin >> n;
while(n--){
z = 0;
cin >> s;
for(i = 0; i < 17; i++){
//身份证号中包含'x'是非法情况,不进行加权计算,直接退出
if(s[i] >= '0' && s[i] <= '9'){ //输入合法性判断
z += (s[i] -'0') * w[i];
}
else
break;
}
//输出非法身份证号
if(jiaoyan[z % 11] != s[17] || i < 17){ //输入的身份证不是数字会提前退出,不是数字也要打印出来
cout << s << endl;
flag++; //标记一下非法
}
}
if(flag == 0) //非法情况为0就是全合法
cout << "All passed";
return 0;
}