身份证号码升位(拷贝构造函数+复合类)

 题目描述:

class CDate

{

private:

int year, month, day;

public:

CDate(int,int,int);

bool check(); //检验日期是否合法

bool isLeap();

void print();

};

class CStudentID

{

private:

char *p_id, *p_name; //身份证号码,姓名

CDate birthday; //出生日期

int registered; //登记否

public:

CStudentID(char *p_idval, char *p_nameval, CDate &day); //构造函数,若:日期非法;日期与id日期不符;id有非法字符;id不是15位或18位;id是18位但检验码不对,则输出"illegal id"并置registered=0。否则输出对象的属性并置registered=1.

CStudentID(const CId &r); //拷贝构造函数,若r.p_id为15位则升到18位(加年份的19和校验位)

bool checked() { return registered; }

~CStudentId();

};

按上述方式定义一个日期类CDate和学生ID类CStudentID。

身份证第18位校验码的生成方法:

1、将身份证号码前17位数分别乘以7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2。然后将其相加

2、将17位数字和系数乘加的和除以11,得到余数。

3、余数与校验码的对应关系为1,0,X,9,8,7,6,5,4,3,2。也即:如果余数是3,身份证第18位就是9。如果余数是2,身份证的最后一位号码就是X。

主函数:

//输入测试次数t

//循环t次

//每次循环中首先输入年月日,并定义日期对象

//然后输入姓名和身份证号码,并先用构造函数定义一个CStudentID对象s,若s.checked()为true,则再用s拷贝构造s_copy对象

输入

测试数据的组数 t

第一个出生日期年月日

第一个姓名,身份证号码

第二个出生日期年月日

第二个姓名,身份证号码

......

输出

第一个CStudent对象s的信息

第一个拷贝构造CStudent对象s_copy输出的信息或者无输出

第二个CStudent对象s的信息

第二个拷贝构造CStudent对象s_copy输出的信息或者无输出

......

输入样例:

6
2018 2 29
张三 440301180229113
1997 4 30
李四 440301980808554
1920 5 8
王五 530102200508011
1980 1 1
赵六 340524198001010012
1988 11 12
钱七 1102038811120A4
1964 11 15
孙八 432831641115081

输出样例:

张三 illegal id
李四 illegal id
王五 1920年5月8日 530102200508011
王五 1920年5月8日 53010219200508011X
赵六 illegal id
钱七 illegal id
孙八 1964年11月15日 432831641115081
孙八 1964年11月15日 432831196411150810

该题需要注意析构函数题干打错,以及拷贝构造函数需要改成CStudentID才能正确执行,不能原封照抄代码框架

AC代码:

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

class CDate {
	private:
		int year, month, day;
	public:
		CDate(int y, int m, int d) {
			year = y;
			month = m;
			day = d;
		}
		int gy() {
			return year;
		}
		int gm() {
			return month;
		}
		int gd() {
			return day;
		}
		bool check() {
			if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
				if (day > 31) {
					return false;
				}
			}
			if (month == 4 || month == 6 || month == 9 || month == 11) {
				if (day > 30) {
					return false;
				}
			}
			if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {
				if (month == 2 && day > 29) {
					return false;
				}
			} else {
				if (month == 2 && day > 28) {
					return false;
				}
			}
			return true;
		} //检验日期是否合法
		bool isLeap();
		void print();

};

class CStudentID {
	private:

		char *p_id, *p_name; //身份证号码,姓名

		CDate birthday; //出生日期

		int registered; //登记否

	public:
		~CStudentID() {
			if (p_name != NULL) {
				delete[]p_name;
			}
			if (p_id != NULL) {
				delete[]p_id;
			}
		}
		bool datelegal() {
			if ((*(p_id + 6) - '0') * 1000 + (*(p_id + 7) - '0') * 100 + (*(p_id + 8) - '0') * 10 + (*
			        (p_id + 9) - '0') == birthday.gy()
			        && (*(p_id + 10) - '0') * 10 + (*(p_id + 11) - '0') == birthday.gm()
			        && (*(p_id + 12) - '0') * 10 + (*(p_id + 13) - '0') == birthday.gd() && strlen(p_id) == 18) {
				return true;
			} else if ((*(p_id + 6) - '0') * 10 + * (p_id + 7) - '0' == birthday.gy() % 100
			           && (*(p_id + 8) - '0') * 10 + (*(p_id + 9) - '0') == birthday.gm()
			           && ( (*(p_id + 10) - '0') * 10 + (*(p_id + 11) - '0') == birthday.gd() )
			           && ( strlen(p_id) == 15) ) {
				return true;
			} else {
				return false;
			}
		}
		bool legalword() {
			if (strlen(p_id) == 15) {
				for (int i = 0; i < 15; i++) {
					if (*(p_id + i) < '0' || *(p_id + i) > '9') {
						return false;
					}
				}
				return true;
			} else if (strlen(p_id) == 18) {
				for (int i = 0; i < 18; i++) {
					if (*(p_id + i) < '0' || *(p_id + i) > '9') {
						return false;
					}
				}
				return true;
			} else {
				return false;
			}
		}
		bool checked() {
			return registered;
		}
		char checkcode() {
			int a[17] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
			int sum = 0;
			for (int i = 0; i < 17; i++) {
				sum = sum + (*(p_id + i) - '0') * a[i];
			}
			sum = sum % 11;
			char b[11] = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
			char res = b[sum];
			return res;
		}

		CStudentID(char *p_idval, char *p_nameval,
		           CDate &day): birthday(
			               day) { //构造函数,若:日期非法;日期与id日期不符;id有非法字符;id不是15位或18位;id是18位但检验码不对,则输出"illegal id"并置registered=0。否则输出对象的属性并置registered=1.
			p_id = new char[strlen(p_idval) + 1];
			strcpy(p_id, p_idval);
			p_name = new char[strlen(p_nameval) + 1];
			strcpy(p_name, p_nameval);
			if (datelegal() && legalword() && birthday.check()) {
				if (strlen(p_id) == 18) {

					if (*(p_id + 17) == checkcode()) {
						cout << p_name << " " << birthday.gy() << "年" << birthday.gm() << "月" << birthday.gd() << "日";
						cout << " " << p_id << endl;
						registered = 1;
					} else {
						cout << p_name << " " << "illegal id" << endl;
						registered = 0;
					}
				} else {
					cout << p_name << " " << birthday.gy() << "年" << birthday.gm() << "月" << birthday.gd() << "日";
					cout << " " << p_id << endl;
					registered = 1;
				}
			} else {
				cout << p_name << " " << "illegal id" << endl;
				registered = 0;
			}

		}
		CStudentID(CStudentID &r): birthday(r.birthday) {
			int i;
			p_name = new char[strlen(r.p_name) + 1];
			strcpy(p_name, r.p_name);
			p_id = new char[strlen(r.p_id) + 4];
			for (i = 0; i < 6; i++) {
				*(p_id + i) = *(r.p_id + i);
			}
			*(p_id + 6) = birthday.gy() / 1000 + '0';
			*(p_id + 7) = birthday.gy() / 100 % 10 + '0';
			for (i = 8; i < 17; i++) {
				*(p_id + i) = *(r.p_id + i - 2);
			}
			*(p_id + 17) = checkcode();
			*(p_id + 18) = '\0';
			cout << p_name << " " << birthday.gy() << "年" << birthday.gm() << "月" << birthday.gd() << "日" ;
			cout << " " << p_id << endl;

		}
		//拷贝构造函数,若r.p_id为15位则升到18位(加年份的19和校验位)
};

int main() {
	int t, y, m, d;
	char name[10];
	char sfz[20];
	cin >> t;
	while (t--) {
		cin >> y >> m >> d;
		CDate obj(y, m, d);
		cin >> name >> sfz;
		CStudentID obj1(sfz, name, obj);
		if (obj1.checked() == 1 && strlen(sfz) == 15) {
			CStudentID obj2(obj1);
		}
	}
}

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 身份证升位通常是指将 15 位身份证升位为 18 位身份证号。具体步骤如下: 1. 将 15 位身份证号码的前 6 位和最后 2 位补齐为 8 位,如将 "110101" 转换为 "11010100"。 2. 在 15 位身份证号码的第 7 、8 位之间插入 "19",即将 "800101" 转换为 "19800101"。 3. 计算身份证号码的校验位。18 位身份证号码的最后一位是校验位,需要通过前 17 位计算得出。具体计算方法为:将前 17 位分别乘以对应的系数并求和,然后将求和结果除以 11,用余数对应的校验码替换掉最后一位即可。系数如下表所示: | 位置 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | | ---- | - | - | - | - | - | - | - | - | - | -- | -- | -- | -- | -- | -- | -- | -- | | 系数 | 7 | 9 | 10 | 5 | 8 | 4 | 2 | 1 | 6 | 3 | 7 | 9 | 10 | 5 | 8 | 4 | 2 | 例如,假设身份证号码前 17 位为 "11010119800101001",则计算校验位的过程如下: ``` (1*7 + 1*9 + 0*10 + 1*5 + 0*8 + 1*4 + 1*2 + 9*1 + 8*6 + 0*3 + 0*7 + 1*9 + 0*10 + 0*5 + 1*8 + 0*4 + 0*2) % 11 = 6 ``` 因此,身份证号码的校验位是 6,将其替换到最后一位即可得到完整的 18 位身份证号码,即 "110101198001010016"。 下面是一个 Python 示例代码,可以将一个 15 位身份证号码升位为 18 位身份证号码: ```python def id_card_upgrade(id_card: str) -> str: if not id_card.isdigit() or len(id_card) != 15: raise ValueError("Invalid ID card number") # 补齐前 6 位和最后 2 位 id_card = id_card[:6] + "19" + id_card[6:] + "00" # 计算校验码 factors = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2] checksum = sum(int(c) * f for c, f in zip(id_card, factors)) % 11 checksum_codes = "10X98765432" checksum_code = checksum_codes[checksum] # 拼接成完整的 18 位身份证号码 return id_card + checksum_code ``` 你可以调用 `id_card_upgrade` 函数将一个 15 位身份证号码升位为 18 位身份证号码,例如: ```python id_card = "110101800101001" upgraded_id_card = id_card_upgrade(id_card) print(upgraded_id_card) # 输出:110101198001010016 ``` ### 回答2: 在Python中,可以使用各种方法对身份证号进行升位操作。以下是一种简单的实现方式: ```python def ascend_id(id_number): """ 输入身份证号并对其升位,返回升位后的身份证号 """ if len(id_number) != 18: # 确保身份证号为18位 return "无效的身份证号" # 获取出生年份 birth_year = int(id_number[6:10]) # 判断出生年份是否在20世纪 if birth_year < 1900 or birth_year >= 2100: return "无效的身份证号" # 将出生年份升位 birth_year += 100 # 将升位后的年份替换原身份证号中的年份 ascended_id = id_number[:6] + str(birth_year) + id_number[10:] return ascended_id # 示例用法 id_number = "320123199001012345" ascended_number = ascend_id(id_number) print(ascended_number) ``` 上述代码中,首先通过判断输入的身份证号是否为18位,以及出生年份是否在合理的范围内(1900年-2099年),来确定输入的身份证号是否有效。 然后,提取出身份证号中的出生年份,并对其进行升位操作,即将年份加100。 最后,将升位后的出生年份替换原身份证号中的年份部分,得到升位后的身份证号。 需要注意的是,本例仅提供了一种简单的实现方式,实际应用中可能需要考虑更多的边界情况和验证逻辑。 ### 回答3: 在Python中,对身份证号进行升位可以通过以下步骤实现: 1. 获取身份证号的前17位数字。身份证号一共18位,前17位为地区和生日信息。 2. 将前17位数字转换为整数型,并加1。这样可以将身份证升位。 3. 将升位后的整数转换为字符串。 4. 根据原身份证号的长度,判断升位后的身份证号是否需要在前面补0。 5. 将升位后的身份证号补全到18位。 6. 检验身份证号的最后一位校验码是否正确。 7. 返回升位后的身份证号。 以下是一个实现上述步骤的Python函数: ```python def increase_idcard(idcard): idcard_prefix = idcard[:17] # 获取前17位数字 idcard_num = int(idcard_prefix) + 1 # 转换为整数并升位 idcard_num_str = str(idcard_num) # 转换为字符串 idcard_length = len(idcard_prefix) # 获取身份证号长度 idcard_new = idcard_num_str.zfill(idcard_length) # 补全升位后的身份证号 idcard_check_num = idcard[-1] # 获取原身份证号校验码 idcard_new_check_num = str(sum(map(lambda x: int(x), idcard_new)) % 10) # 计算升位身份证号的校验码 if idcard_new_check_num == '0': idcard_new_check_num = 'X' if idcard_new_check_num != idcard_check_num: # 校验码错误 return '' return idcard_new # 身份证升位示例 idcard = '11010120200818888X' idcard_new = increase_idcard(idcard) print(idcard_new) ``` 注意:升位后的身份证号仅在前17位数字上升,校验码保持不变,因此升位可能导致身份证号不符合实际规则,仅用作示例说明。此外,对于真实的身份证号,一般不建议随意修改或升位

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Shiroha Wang

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值