PTA |1031 查验身份证 分数 15

184 阅读2分钟

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

每个s[i]×w[i] s[i]×w[i]都会得到一个乘积,我们把这个乘积分别mod10 mod 10 , 都会得到一个值z z,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;       
}