IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> E. 新旧身份证(继承) -> 正文阅读

[C++知识库]E. 新旧身份证(继承)

题目描述

按下述方式定义一个日期类CDate和描述15位身份证号的旧身份证类COldId:

class CDate
{

private:
	int year, month, day;
public:
	CDate(int, int, int);
	bool check(); //检验日期是否合法
	bool isLeap();
	void print();
};

class COldId
{
protected:
	char* pId15, * pName; //15位身份证号码,姓名
	CDate birthday; //出生日期
public:
	COldId(char* pIdVal, char* pNameVal, CDate& day);
	bool check(); //验证15位身份证是否合法
	void print();
	~COldId();
};
然后以COldId为基类派生18位身份证号的新身份证类CNewId,并增加3个数据成员:pId18(18位号码)、issueDay(签发日期)和validYear(有效期,年数),并重新定义check()和print()。

身份证第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。

主函数定义一个派生类对象,并用派生类对象调用check(),若返回false则输出“illegal id”否则调用print()输出身份证信息。check()对身份证合法性进行验证的规则:

1. 确认18位号码是从15位号码扩展的,且第18位校验码正确.

2. 身份证中的出生日期合法.

3. 身份证号码中不含非法字符.

4. 身份证号码的长度正确.

5. 身份证目前处于有效期内,假设当前日期为2021年11月8日。


输入

测试数据的组数 t

第一个人姓名、出生日期年月日、15位身份证号码、18位身份证号码、签发日期年月日、有效期(100年按长期处理)

第二个人姓名、出生日期年月日、15位身份证号码、18位身份证号码、签发日期年月日、有效期(100年按长期处理)

......

姓名的最大字符长度为20


输出

第一个人姓名

第一个人18位身份证号信息(号码、签发日期和有效期)或"illegal id"

第二个人姓名

第二个人18位身份证号信息(号码、签发日期和有效期)或"illegal id"

......


输入样例1 
10
AAAA 1988 2 28 440301880228113 440301198802281133 2006 1 20 20
BBBB 1997 4 30 440301980808554 440301199808085541 2015 2 2 10 
CCCC 1920 5 8 530102200508011 53010219200508011X 1980 3 4 30
DDDD 1980 1 1 340524800101001 340524198001010012 1998 12 11 20
EEEE 1988 11 12 110203881112034 110203198811120340 2007 2 29 20 
FFFF 1964 11 15 432831641115081 432831196411150810 2015 8 7 100
GGGG 1996 12 10 44030196121010 44030119961210109 2014 6 7 20
HHHH 1988 7 21 440301880721X12 44030119880721X122 2006 5 11 20
IIII 1976 3 30 440301760330098 440301197603300983 2003 4 15 20
JJJJ 1955 9 5 440301550905205 440301195509051052 2004 6 4 100 

输出样例1
AAAA
440301198802281133 2006年1月20日 20年
BBBB
illegal id
CCCC
illegal id
DDDD
illegal id
EEEE
illegal id
FFFF
432831196411150810 2015年8月7日 长期
GGGG
illegal id
HHHH
illegal id
IIII
illegal id
JJJJ
illegal id

该题题目很长,好好审题再动手,该题的难点主要在check()的实现上

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include <iomanip>
#include<cmath>
#include<cstring>
#include<cctype>
#include<queue>
#include<set>
using namespace std;

class CDate
{
private:
	int year, month, day;
public:
	CDate() { ; }
	CDate(int y, int m, int d)
	{
		year = y;
		month = m;
		day = d;
	}
	bool check(); //检验日期是否合法
	bool isLeap();
	int gety() { return year; }
	int getm() { return month; }
	int getd() { return day; }
	void print()
	{
		cout << year << "年" << month << "月" << day << "日";
	}
	void set(int y, int m, int d)
	{
		year = y;
		month = m;
		day = d;
	}
};

class COldId
{
protected:
	string pId15,pName; //15位身份证号码,姓名
	CDate birthday; //出生日期
public:
	COldId() { ; }
	//COldId(string pIdVal, string pNameVal, CDate& day);
	//bool check(); //验证15位身份证是否合法
	//void print();
	//~COldId();
};

class cnewid :public COldId
{
protected:
	string pid18;
	CDate issueDay;
	int validyear;
public:
	cnewid(string name, string id1, string id2, int y, int m, int d, int yy, int mm, int dd,int age);
	bool check();
	void print();
};

void cnewid::print()
{
	if (this->check())
	{
		cout << pid18 << ' ';
		issueDay.print();
		if (validyear != 100)
		{
			cout << ' '<<validyear << "年" << endl;
		}
		else
		{
			cout << ' ' << "长期" << endl;
		}
	}
	
}

bool cnewid::check()
{
	if (pid18.length() == 18)//身份证长度是否合格
	{
		string id = pid18;
		string date = id.substr(6, 8);
		string str = id.erase(6, 2);
		int len = pid18.length();
		str = str.erase(15);
		int y = (date[0] - 48) * 1000 + (date[1]-48) * 100 + (date[2]-48) * 10 + (date[3]-48);
		int m = (date[4] - 48) * 10 + (date[5] - 48);
		int d = (date[6] - 48) * 10 + (date[7] - 48);
		int num = this->issueDay.gety()*10000 +this->issueDay.getm()  * 100 + this->issueDay.getd();
		CDate D(y, m, d);
		num += (validyear * 10000);
		if (D.check()&&str==pId15&&num>=20211108&&y==this->birthday.gety()&& m == this->birthday.getm()&& d == this->birthday.getd()&&issueDay.check())
		{//身份证中的出生日期是否合格+18位身份证是否由15位扩展来的+身份证是否过期+身份证签发日期是否合格
			int sign = 1;
			for (int i = 0; i < len; i++)
			{
				if (pid18[i] == 'X' && i != 17)
				{
					sign = 0;
					break;
				}
				if ((pid18[i] >= '0' && pid18[i] <= '9'))
				{
					sign = 1;
				}
				else
				{
					sign = 0;
					break;
				}
			}
			if (sign)//身份证是否出现非法符号
			{
				int n = (pid18[0] - 48) * 7 + (pid18[1] - 48) * 9 + (pid18[2] - 48) * 10 + (pid18[3] - 48) * 5 + (pid18[4] - 48) * 8 + (pid18[5] - 48) * 4 + (pid18[6] - 48) * 2 + (pid18[7] - 48) + (pid18[8] - 48) * 6 + (pid18[9] - 48) * 3 + (pid18[10] - 48) * 7 + (pid18[11] - 48) * 9 + (pid18[12] - 48) * 10 + (pid18[13] - 48) * 5 + (pid18[14] - 48) * 8 + (pid18[15] - 48) * 4 + (pid18[16] - 48) * 2;
				n %= 11;
				char dui;
				if (n == 0)
					dui = '1';
				else if (n == 1)
					dui = '0';
				else if (n == 2)
					dui = 'X';
				else if (n == 3)
					dui = '9';
				else if (n == 4)
					dui = '8';
				else if (n == 5)
					dui = '7';
				else if (n == 6)
					dui = '6';
				else if (n == 7)
					dui = '5';
				else if (n == 8)
					dui = '4';
				else if (n == 9)
					dui = '3';
				else if (n == 10)
					dui = '2';
				if (dui == pid18[17])//身份证校验码是否正确
				{
					return true;
				}
			}
		}
	}
	return false;
}

cnewid::cnewid(string name, string id1, string id2, int y, int m, int d, int yy, int mm, int dd,int age)
{
	pName = name;
	birthday.set(y, m, d);
	pId15 = id1;
	pid18 = id2;
	issueDay.set(yy, mm, dd);
	validyear = age;
}

bool CDate::isLeap()
{
	return ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0));
}

bool CDate::check()
{
	int m[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	if (this->isLeap()) m[2] = 29;
	else m[2] = 28;
	if (month >= 1 && month <= 12 && day >= 1 && day <= m[month])
	{
		return true;
	}
	return false;
}
int main()
{
	int t, y, m, d, yy, mm, dd, age;
	string OLD, NEW,name;
	cin >> t;
	while (t--)
	{
		cin >> name >> y >> m >> d >> OLD >> NEW>>yy >> mm >> dd >> age;
		cnewid per(name, OLD, NEW, y, m, d, yy, mm, dd, age);
		cout << name << endl;
		if (per.check())
		{
			per.print();
		}
		else
		{
			cout << "illegal id" << endl;
		}
	}
	return 0;
}

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-05 10:59:30  更:2022-05-05 11:03:25 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/21 5:56:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码