PTAL1-016 查验身份证 c++实现 多种方法 多种细节

文章讨论了C++代码实现的身份证号码校验问题,包括对题目理解的误区、代码优化建议以及三种不同的解决方案:使用不同数据结构、back()函数和创建类。作者强调了代码清晰性和易读性的重要性,并提供了更优的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

先上代码

我遇到的问题

首先,对题目的理解

其次,是对代码的优化问题

最后,返回值

多种解法

1.换种数据结构

2.back()函数

3.类


先上代码

#include<iostream>
#include<string>
#include<vector>
using namespace std;
char c[11]={'1','0','X','9','8','7','6','5','4','3','2'};
int b[17]={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
int check_pass (string a);
int main(){
    int N;
    cin>>N;
    vector<string> a(N);
    for(int i=0;i<N;i++){
        cin>>a[i];
    }
    int j=0;
    int recored_=0;
    for(int i=0;i<N;i++){
        j=check_pass(a[i]);
        if(j==-1){
            cout<<a[i]<<endl;
            recored_=-1;
        }
    }
    if(recored_==0){
        cout<<"All passed";
    }
    
    
}
int check_pass (string a){
    int sum=0;
    int z=0;
    for(int i=0;i<17;i++){
        sum+=(a[i]-'0')*b[i];
    }
    z=sum%11;
    if(c[z]==a[17]){
        return 1;
    }
    else{
        return -1;
    }
}

 

我遇到的问题

首先,对题目的理解

首先是没有意识到身份证号码是18位的,其次对加权求和的理解不准确,认为是“加”权,实际上是乘,这直接导致我的代码错误,只过一个测试点。加权求和是指对一组数字,按照一定的权重分配,将每个数字乘以对应的权重,然后将所有乘积相加得到一个结果。

其次,是对代码的优化问题

动态数组用vector或者new要比直接定义string a[N]要好,

最后,返回值

用bool类型比int更好,为了避免将 0 或 1 作为返回值的误判,函数 check_pass 的返回值最好定义为 bool 类型。同时,将 recored_ 的数据类型修改为 bool 类型。因为bool类型只有true和false两个值,没有其他的可能性,所以不会出现误判。

最重要的是,直观!!!!  不管谁看,一眼就知道,直观!     

可以降低错误的概率,你想,你代码量少还行,但一旦一多,就容易出问题,看花眼。

而且别人看你代码,也晕。害己害人。

多种解法

1.换种数据结构

用结构体进行封装,当然,也可以用类

#include <iostream>
#include <string>
using namespace std;

// 定义结构体,用于存储身份证号码
struct ID {
    string id;
    bool is_valid; // 是否合法
};

// 验证身份

2.back()函数

#include <iostream>
#include <string>
using namespace std;

bool check_pass(const string& a) {
    static int b[] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
    static char c[] = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
    int sum = 0;
    for (size_t i = 0; i < 17; ++i)
        sum += (a[i] - '0') * b[i];
    int z = sum % 11;
    if(c[z]==a.back()){
        return true;
    }
    else{
        return false;
    }
}

int main() {
    int n;
    cin >> n;
    string s;
    bool all_passed = true;
    for (int i = 0; i < n; ++i) {
        cin >> s;
        if (!check_pass(s)) {
            cout << s << endl;
            all_passed = false;
        }
    }
    if (all_passed) {
        cout << "All passed" << endl;
    }
    return 0;
}

3.类

#include <iostream>
#include <string>
#include <vector>

using namespace std;

class IDNumber {
public:
    IDNumber(const string &s) : id_(s) {}

    bool check() const {
        static int b[] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
        static char c[] = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};

        if (id_.size() != 18) return false;

        int sum = 0;
        for (size_t i = 0; i < 17; ++i)
            if (!isdigit(id_[i])) return false;
            else sum += (id_[i] - '0') * b[i];

        return id_[17] == c[sum % 11];
    }

    const string &get() const {
        return id_;
    }
//这是一个C++类的成员函数,函数名为get,返回类型为const string&,并且是一个常量成员函数。常量成员//函数是指在函数内部不能修改对象的成员变量,以保证对象的状态不会被修改。

//这个函数的作用是返回对象的私有成员变量id_的值,并且由于是常量成员函数,所以可以在对象的const函数//中被调用,以保证不会修改对象的状态。

private:
    string id_;
};

int main() {
    int n;
    cin >> n;
    vector<IDNumber> ids;
    for (int i = 0; i < n; ++i) {
        string s;
        cin >> s;
        ids.emplace_back(s);
        //ids.emplace_back(s) 是将字符串 s 添加到 vector<string> ids 的尾部,可以理解为在 ids                   //中增加一个元素,并将 s 赋值给这个元素。这里使用了 C++11 中的 emplace_back() 函数,它相比 //push_back() 函数的优势在于可以在不产生中间对象的情况下直接将元素添加到容器中,从而提高了效率。
      
    }

    bool all_passed = true;
    for (const auto &id : ids) {
        if (!id.check()) {
            cout << id.get() << endl;
            all_passed = false;
        }
    }

    if (all_passed) cout << "All passed" << endl;

    return 0;
}

在上面的代码中,我们定义了一个名为IDNumber的类,用于表示身份证号码。在该类的构造函数中,我们接受一个身份证号码字符串并将其存储在私有变量id_中。我们还为IDNumber类定义了两个公有函数:checkget

check函数用于检查身份证号码的校验码是否正确。具体地,我们使用权重分配数组b对前17位数字进行加权求和,并计算其对11取模的结果z。然后根据z的值与预设的校验码字符数组c的对应关系,比较z和最后一位校验码字符,判断校验码是否正确。如果校验码正确,check函数返回true,否则返回false

get函数用于获取存储在IDNumber对象中的身份证号码字符串。

在主函数中,我们使用vector<IDNumber>存储所有输入的身份证号码,并使用for循环依次检查每个身份证号码的校验码是否正确。如果某个身份证号码的校验码不正确,我们输出该号码并将all_passed变量设为false。最后,如果所有身份证号码的校验码都正确,我们输出All passed

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

amojiacoco

请我杯饮料吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值