C++实验课——继承


提示:以下是本篇文章正文内容,下面案例可供参考

【id:73】【20分】C. 时钟模拟(继承)

题目描述

定义计数器类,包含保护数据成员value,公有函数increment计数加1。

定义循环计算器继承计数器类,增加私有数据成员:最小值minValue,maxValue,

重写公有函数increment,使得value在minValue~maxValue区间内循环+1。

定义时钟类,数据成员是私有循环计数器对象小时hour、分钟minute、秒second,公有函数time(int s)计算当前时间经过s秒之后的时间,即hour,minute,second的新value值。

定义时钟类对象,输入当前时间和经过的秒数,调用time函数计算新时间。

根据题目要求,增加必要的构造函数、析构函数和其他所需函数。

因为clock和time是系统内置函数,为了避免重名,请不要使用clock或者time作为类名或者函数名


输入

第一行测试次数n

2行一组,第一行为当前时间(小时 分钟 秒),第二行为经过的秒数。

输出

输出n行

每行对应每组当前时间和经过秒数后计算得到的新时间(小时:分钟:秒)。


输入样例

2
8 19 20
20
23 30 0
1801

输出样例

8:19:40
0:0:1

本题思路:主要是进位问题需要解决。

#include<iostream>
using namespace std;

class Counter
{
protected:
    int value;
public:
    Counter(int v);
    void increment();
};

Counter::Counter(int v)
{
    value = v;
}

void Counter::increment()
{
    value+=1;
}

class CycleCounter:public Counter
{
private:
    int minValue;
    int maxValue;
public:
    CycleCounter(int v, int min_v, int max_v);
    void increment();
    int getValue();
};

CycleCounter::CycleCounter(int v, int min_v, int max_v):Counter(v)
{
    minValue = min_v;
    maxValue = max_v;
}

void CycleCounter::increment()
{
    if (value + 1 == maxValue)
    {
        value = minValue;  //达到最大值就归为最小值
    }
    else
    {
        value += 1;
    }
}
int CycleCounter::getValue()
{
    return value;
}

class The_Clock 
{
private:
    CycleCounter hour;
    CycleCounter minute;
    CycleCounter second;
public:
    The_Clock(int h, int m,int s);
    void count_time(int s);
    void print();
};

The_Clock::The_Clock(int h, int m, int s) :hour(h, 0, 24), minute(m, 0, 60), second(s, 0, 60)
{

}
void The_Clock::count_time(int s)
{
    while (s--)
    {
        second.increment(); //先增加
        if (second.getValue() == 0)  //判断是否为0,为0就说明是增大到最大值然后归0了,要进位
        {
            minute.increment();//分钟加1
            if (minute.getValue() == 0) //同上,判断分钟是否要进位
            {
                hour.increment();
            }
        }
    }
}
void The_Clock::print()
{
    cout << hour.getValue() << ":" << minute.getValue() << ":" << second.getValue() << endl;
}

int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        int h, m, s, t;
        cin >> h >> m >> s >> t;
        The_Clock now(h,m,s);
        now.count_time(t);
        now.print();
    }
    //system("pause");
    return 0;
}

【id:74】【20分】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"


输入样例

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 

输出样例

AAAA
440301198802281133 200612020年
BBBB
illegal id
CCCC
illegal id
DDDD
illegal id
EEEE
illegal id
FFFF
432831196411150810 201587日 长期
GGGG
illegal id
HHHH
illegal id
IIII
illegal id
JJJJ
illegal id

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

class CDate // 日期类定义 
{

private:
	int year, month, day;
public:
	CDate(); //需要用到无参构造 
	CDate(int, int, int);
	bool check(); //检验日期是否合法
	bool isLeap();
	void print();
	int get_year();
	int get_month();
	int get_day();
};

int CDate::get_year()
{
	return year;
}

int CDate::get_month()
{
	return month;
}

int CDate::get_day()
{
	return day;
}

//CDate::CDate()
//{
//
//}

CDate::CDate(int y, int m, int d)
{
	year = y;
	month = m;
	day = d;
}

bool CDate::check() //判断日期是否合法,主要判断闰年和非闰年的二月份(本题测试数据只需这样判断) 
{
	if (isLeap()&&month==2) // 闰年二月判断 
	{
		if (day == 28)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	if (!isLeap() && month == 2)  //非闰年二月判断 
	{
		if (day == 29)
		{
			return false;
		}
	}
	return true;
}
void CDate::print()
{
	cout << year << "年" << month << "月" << day << "日";
}
bool CDate::isLeap()  //闰年判断 
{
	return (year % 4 == 0 && year % 100 != 0 || year % 400 == 0);
}
class COldId
{
protected:
	char* pId15, * pName; //15位身份证号码,姓名
	CDate birthday; //出生日期
public:
	COldId(char* pIdVal, char* pNameVal, int y,int m,int d);
	bool check(); //验证15位身份证是否合法
	void print();
	~COldId();
};

COldId::COldId(char* pIdVal, char* pNameVal, int y,int m,int d):birthday(y,m,d)
{
	pId15 = new char[20];
	pName = new char[20];
	for (int i = 0; i < 20; i++)
	{
		pId15[i] = pIdVal[i];
	}
	for (int i = 0; i < 30; i++)
	{
		pName[i] = pNameVal[i];
	}
}

bool COldId::check()
{
	if (strlen(pId15) != 15) //判断长度 
	{
		return false;
	}
	for (int i = 0; i < 15; i++)  //非法字符判断 
	{
		if ('0' > *(pId15 + i) || *(pId15 + i) > '9')
		{
			return 0;
		}
	}
	if (birthday.check() == 0)  //判断身份证的出生日期合法 
	{
		return false;
	}
	if((pId15[6]-'0')*10+(pId15[7]-'0')!=birthday.get_year()%100||
		(pId15[8]-'0')*10+(pId15[9]-'0')!=birthday.get_month()||
		(pId15[10] - '0') * 10 + (pId15[11] - '0') != birthday.get_day()) // 校验身份证第6、7、8、910、11位是否与生日年份后两位,月份及日期对应 
	{
		return false;
	}
	return true;
}

void COldId::print()
{
	cout << pName << endl;
}

COldId::~COldId()
{
	delete[]pId15;
	delete[]pName;
}

class CNewId :virtual public COldId
{
private:
	char* pId18;
	CDate issueDay;
	int validYear;
public:
	CNewId(char *n,int y1,int m1,int d1,char*p15,char*p18,int y2,int m2,int d2,int v);
	~CNewId();
	char* update();
	bool check();
	void print();
	int vaild();
};
CNewId::CNewId(char* n, int y1, int m1, int d1, char* p15, char* p18, int y2, int m2, int d2, int v) : COldId(p15, n, y1,m1,d1), issueDay(y2, m2, d2), validYear(v)
{
	pId18 = new char[30];
	//strcpy(pId18, p18);
	for (int i = 0; i<30; i++)
	{
		pId18[i] = p18[i];
	}
	//pId18[strlen(p18) + 1] = '\0';
}

CNewId::~CNewId()
{
	delete []pId18;
}

char*CNewId:: update() //升级 
{
	static char new_id[20];
	for (int i = 0; i < 6; i++)
	{
		new_id[i] = pId15[i];
	}
	if (birthday.get_year() < 2000)
	{
		new_id[6] = '1';
		new_id[7] = '9';
	}
	else
	{
		new_id[6] = '2';
		new_id[7] = '0';
	}
	for (int i = 8; i < 17; i++)
	{
		new_id[i] = pId15[i-2];
	}
	int add[17] = { 7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2 };
	char last[12] = { '1','0','X','9','8','7','6','5','4','3','2','\0' };
	int sum = 0;
	for (int i = 0; i < 17; i++)
	{
		sum += ((new_id[i] - '0') * add[i]);
	}
	sum %= 11;
	new_id[17] = last[sum];
	new_id[18] = '\0';
	return new_id;
}
int CNewId::vaild()//判断是否在有效期内 
{
	return (issueDay.get_year() + validYear > 2015 ||
		((issueDay.get_year() + validYear) == 2015 && issueDay.get_month() < 4) ||
		((issueDay.get_year() + validYear) == 2015 && issueDay.get_month() == 4 && issueDay.get_day() < 7));
}

bool CNewId::check()
{
	if (strcmp(update(), pId18) != 0 || !issueDay.check() || !vaild())//两个字符串相同返回0。两字符串不相同、签发日期有问题 、不在有效期内 
	{
		return 0;
	}
	else
	{
		return 1;
	}
}

void CNewId::print()
{
	cout << pId18 << " " << issueDay.get_year() << "年" << issueDay.get_month() << "月" << issueDay.get_day() << "日 ";
	if (validYear == 100)
	{
		cout << "长期" << endl;
	}
	else
	{
		cout << validYear <<"年"<< endl;
	}
}

int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		char name[20];
		int bir_y, bir_m, bir_d;
		char* p15 = new char[20];//预留多几个字节空间,测试数据可能给超15的数据 
		char* p18 = new char[30];//同上 
		int qian_y, qian_m, qian_d;
		int youxiao;
		cin >> name >> bir_y >> bir_m >> bir_d >> p15 >> p18 >> qian_y >> qian_m >> qian_d >> youxiao;
		CNewId newID(name, bir_y, bir_m, bir_d, p15, p18, qian_y, qian_m, qian_d, youxiao);
		newID.COldId::print();
		if (newID.COldId::check() && newID.check())//注意:旧的身份证也需要检查 
			newID.print();
		else
			cout << "illegal id" << endl;
	}

    system("pause");
    return 0;
}

总结

继承这块掌握的不是很熟练。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
吉林大学C实验课是一门专门针对计算机科学与技术专业的实践课程。通过这门课程,学生将有机会接触并了解计算机科学领域中的实际问题,并通过实验的方式来解决这些问题。这门课程的目标是让学生能够熟练掌握计算机科学与技术的实践能力,为将来工作或学术研究打下坚实的基础。 在吉林大学C实验课中,学生将进行一系列的实验项目,以提高他们的实践能力。这些实验项目涵盖了计算机科学与技术的不同领域,例如软件开发、网络安全、数据库应用等。通过实验项目,学生将能够学习和掌握计算机领域中的先进技术和工具,同时也培养他们的团队合作和问题解决能力。 吉林大学C实验课的教学方法包括课堂教学和实验室实践。在课堂教学中,教师将向学生介绍实验项目的背景和目标,讲解相关的理论知识和实验步骤。学生将通过听课和课后学习来掌握这些知识。在实验室实践中,学生将亲自动手进行实验项目,实践他们在课堂上学到的知识和技能。同时,教师将提供指导和支持,确保学生能够顺利完成实验项目。 通过参加吉林大学C实验课,学生将能够深入了解和实践计算机科学与技术的领域,提高他们的实践能力和创新能力。这将为他们未来的就业或学术研究提供有力的支持。此外,吉林大学C实验课还将培养学生的团队合作和沟通能力,让他们能够更好地适应和应对现实工作环境中的挑战。 总之,吉林大学C实验课是一门重要的实践课程,它将帮助学生提高他们的实践能力和创新能力,为他们未来的就业或学术研究奠定坚实的基础。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值