• 题目-查验身份证


    题目-查验身份证

    一个合法的身份证号码由17位地区、日期编号和顺序编号加1位校验码组成。校验码的计算规则如下:
    首先对前17位数字加权求和,权重分配为:{7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};然后将计算的和对11取模得到值Z;最后按照以下关系对应Z值与校验码M的值:
    Z:0 1 2 3 4 5 6 7 8 9 10
    M:1 0 X 9 8 7 6 5 4 3 2
    现在给定一些身份证号码,请你验证校验码的有效性,并输出有问题的号码。

    输入格式

    输入第一行给出正整数N(≤100)是输入的身份证号码的个数。随后N行,每行给出1个18位身份证号码。

    输出格式

    按照输入的顺序每行输出1个有问题的身份证号码。这里并不检验前17位是否合理,只检查前17位是否全为数字且最后1位校验码计算准确。如果所有号码都正常,则输出All passed

    输入样例1

    4
    320124198808240056
    12010X198901011234
    110108196711301866
    37070419881216001X

    输出样例1

    12010X198901011234
    110108196711301866
    37070419881216001X

    输入样例2

    2
    320124198808240056
    110108196711301862

    输出样例2

    All passed

    具体分析

    验证一个身份证号码的校验码准确性的步骤是:

      ①检验前17位是否全为数字:否则判定为有问题的身份证号码,需要输出该号码;是则进行下一步;

      ②计算:前17位的加权和 Sum → Sum 对11取模得 Z 值 → 按照对应关系得 M值;

      ③验证 Z值对应的 M值与第18位是否一致:一致则 passed,不一致则判定为有问题的身份证号码进而输出。

    本题需要验证 N 个身份证号码,要把上述步骤框进一个循环 N 次的循环体中。

    把 M 的值存放进一维字符数组 M[11] 中会发现 Z 的值就是数组的下标,故在表示 Z 和 M 之间的对应关系时可以用一维数组代替二维数组。

    身份证中含有字母‘X’,所以18位身份证号码的数据类型为字符型数组,数字在字符数组中存放的是ASCII码,直接用 char 类型的数字计算时实际是其ASCII码值参与计算,因此在计算前需要进行转化:数字数值 = 其ASCII码值 - 48。

    输出 "All passed" 的条件是所有号码都正常,即只要没有号码被输出,就输出 "All passed",设置一个 wrong 标志查验有无输出号码。

    代码

     1 #include<iostream>
     2 using namespace std;
     3 
     4 int main()
     5 {
     6     int N, i, j, t, wrong(0); //N为号码个数,i、j、t都是辅助变量,wrong标志有无出错号码  
     7     cin >> N;
     8     
     9     char ID[N][18];    //输入18位身份证号码,因为有‘X’,为字符型 
    10     for(i=0; i<N; i++){
    11         for(j=0; j<18; j++){
    12             cin >> ID[i][j];
    13         } 
    14     }
    15      cout << endl; //为了更直观看输出结果 
    16     
    17     char M[11]={'1','0','X','9','8','7','6','5','4','3','2'};    //校验码 
    18     int q[17]={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};             //权重   
    19     
    20     for(i=0; i<N; i++){ //按输入的顺序逐个检验号码  
    21         for(j=0; j<17; j++){
    22             if(ID[i][j]>'9' || ID[i][j]<'0')
    23             { //前17位中一旦有非数字,便直接判定为有问题的身份证号码,并输出该号码 
    24                 for(t=0; t<18; t++){
    25                     cout << ID[i][t];
    26                     wrong = 1; //有出错号码 
    27                 }
    28                 cout << endl;
    29                 break; //前往检验下一个号码 
    30             }
    31             else{   
    32                 if(j==16){                     //前17位全为数字,设置验算断点  
    33                     int cal[17];             //用于计算数值的一维整型数组,存放前17位数字  
    34                     int Sum=0, Z;            //权重之和 Sum, 取模得值 Z 
    35                     for(t=0; t<17; t++){     //1.将 char 转换为 int
    36                         cal[t] = ID[i][t] - 48; //数字的ASCII码值比数字的数值大48  
    37                     }
    38                     for(t=0;t<17;t++){         //2.计算加权和 
    39                         Sum = Sum + cal[t]*q[t];
    40                     }
    41                     Z = Sum % 11; //取模得 Z 值   
    42                     if(M[Z] != ID[i][17]){     //3.校验码不准确时输出有问题的身份证号  
    43                         for(t=0; t<18; t++){
    44                             cout << ID[i][t];
    45                             wrong = 1;
    46                         }
    47                         cout << endl;
    48                     } //校验码准确则 passed 
    49                 }
    50             }
    51         }
    52     }
    53     if(wrong == 0){ //没有输出过号码,即所有号码都正常  
    54         cout << "All passed" << endl;
    55     }
    56     
    57     return 0; 
    58 }
     
  • 相关阅读:
    legend3---阿里云如何多个域名指向同一个网站
    黑马lavarel教程---1、lavarel目录结构
    modern php笔记---2.1、特性(命名空间、特性、性状)
    modern php笔记---php (性状)
    modern php笔记---1、新时代的php
    深入浅出mysql笔记---1、mysql下载安装
    深入浅出mysql笔记---0、序
    影视感悟专题---2、《大染坊》
    尚硅谷Docker---6-10、docker的安装
    legend3---Homestead常用操作代码
  • 原文地址:https://www.cnblogs.com/yuanchuying/p/14754331.html
Copyright © 2020-2023  润新知