天梯赛 L1-016 查验身份证 (15分) 附stringstream用法

L1-016 查验身份证 (15分)

一个合法的身份证号码由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

答案1

#include <iostream>
#include <stdio.h>
#include <sstream>
#include <string>

using namespace std;

int main(){
    int n;
    cin >> n;
    char m[11] = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
    int q[17] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
    int sum = 0;
    
    string id;
    int x = n;
    while(n--){
        int flag = 0;    //注意这个flag要设在while循环内
        cin >> id;
        for(int i = 0; i < 17; i++){
            if(id[i] < '0' || id[i] > '9'){
                cout << id << endl;
                flag = 1;
                break;
            }
        }
        int s = 0;
        if(!flag){
            for(int i = 0; i < 17; i++){
                int p;
                stringstream convert;
                convert << id[i];
                convert >> p;
                s += p*q[i];
            }
            s %= 11;
            if(m[s] == id[17])
                sum ++;     //记录通过数
            else
                cout << id << endl;
        }

    }
    if(sum == x)
        cout << "All passed" << endl;
    return 0;
}

stringstream

stringstream 是 中定义的类,流的输入输出操作。

主要用来进行数据类型转换

int 转化为string

#include <string>
#include <sstream>
#include <iostream>
#include <stdio.h>

using namespace std;

int main(){
    stringstream convert;
    string str;
    int n = 1234;
    convert << n;   //int 类型放入输入流中
    convert >> str;  //赋给string类型
    cout << str << endl;
    prinf("%s\n", str.c_str());
    return 0;
}

字符串拼接

#include <string>
#include <sstream>
#include <iostream>

using namespace std;

int main(){
    stringstream convert;
    convert << "abc";      
    convert << "opq";                 //拼接后
    cout << convert.str() << endl;    //str方法将stringstream类型转化为string类型

    convert.str("");                  //清空
    convert << "xyz";
    cout << convert.str() << endl;    //清空后重新赋

    return 0;
}

答案2

这个答案来源于网上,不过找不到是哪位写的了QAQ

#include <iostream>
#include <string>

using namespace std;

bool func(string s){
    int sum = 0;
    int a[18];
    for(int i = 0; i < 17; i++){
        if(!isdigit(s[i])){        //isdigit是计算机C(C++)语言中的一个函数,主要用于检查其参数是否为十进制数字字符。
            cout << s << endl;
            return true;   //这里原代码写的是 return false, 我怎么觉得应该是true? 但是不管是true or false 都通过了测试点...
        }
        a[i] = s[i] - '0';
    }
    if(s[17] == 'X')
        a[17] = 10;
    else
        a[17] = s[17] - '0';

    int b[17] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
    for(int i = 0; i < 17; i++){
        sum += a[i]*b[i];   //原代码是sum = sum +, 用 += 更简洁
    }
    sum %= 11;
    int c[11] = {1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2};
    if(c[sum] != a[17]){
        for(int i = 0; i < 17; i++){
            cout << s[i];
        }
        if(a[17] != 10)
            cout << a[17] << endl;
        else{
            cout << "X" << endl;
        }
        return true;
    }
    else{
        return false;
    }
}

int main(){
    int n;
    int count = 0;
    cin >> n;
    for(int i = 0; i < n; i++){
        string a;
        cin >> a;
        if(func(a))
            count ++;
    }
    if(count == 0)
        cout << "All passed";
    return 0;
}
发布了44 篇原创文章 · 获赞 0 · 访问量 1325

猜你喜欢

转载自blog.csdn.net/qq_41664688/article/details/104142871