学生生日差值计算(运算符重载)

题目描述

定义一个学生类Student,包含该学生的姓名、出生年、月、日 ,重定义 “-”号实现两个学生之间相差多少天的比较。并利用重载的“-”运算符,求所有学生中年龄相差最大的两个人的名字以及相差天数。

输入

第一行:输入所需要输入的学生个数;

第二行开始,依次输入每个学生的姓名、出生年、月、日。

输出

输出年龄相差最大的两个人的名字以及相差天数。

输入样例1

3
Tom 1995 1 1
Joe 1995 2 28
Jimmy 1996 1 8

输出样例1

Tom和Jimmy年龄相差最大,为372天。

思路分析

首先来看怎么计算两个日期之间的天数。

分析

对于输入进来的year、month和day,我们分三种情况计算。

最简单的情况,月份相同

直接两个day相减返回完事,从不拖泥带水。

然后是年份相同

首先判断一下是不是闰年,如果是闰年,把2月改成29天。

之后我们一个非常关键的函数必须用上,这个函数我们用来计算从当前日期开始直到过完本年的总天数,就是还有多少天过完这一年,即本年的剩余天数,我们把它暂时叫做remaindays,它的模样具体看代码。

有了这个函数之后呢,年份相同的情况就可以直接通过前一个日期本年剩余天数减去后一个日期本年剩余天数。

最后是年份不同的情况

首先我们先把这一年过完,即先调用remaindays函数计算本年剩余天数吗,然后年份自增直到和后一个年份相等,从整体来看到底差了多少年,差的每一年都来判断是否是闰年,是的话加上366天,不是的话就加上365天,这样一波下来,可以想到我们算多了天数,算多了后一个日期的本年剩余天数,最后把它减去完事。

额外

对于输入进来的前一个日期晚于后一个日期的情况,我们输出-1。

其他

首先我们看这两个日期之间的天数是不是负数,如果是那么我们调换一下顺序再算一次。

在主函数中我们开辟数组,然后两层循环找最大差值,不过我好像忘记delete申请的内存了。

AC代码

#include"iostream"
#include"string"
using namespace std;
class Date
{
	int year, month, day;
public:
	void set(){cin>>year>>month>>day;}
	bool isleap(int year)
	{
		if (year % 400 == 0 || year % 4 == 0 && year % 100 != 0)
			return 1;
		return 0;
	}
	int remaindays()
	{
		long days;
		int i,leapyear[12] = { 31,29,31,30,31,30,31,31,30,31,30,31 },normalyear[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
		if (isleap(year))
		{
			days = leapyear[month - 1] - day;
			for (i = month; i < 12; i++)
				days += leapyear[i];
		}
		else
		{
			days = normalyear[month - 1] - day;
			for (i = month; i < 12; i++)
				days += normalyear[i];
		}
		return days;
	}
	friend int CountDay(Date &a,Date &b);
};
int CountDay(Date &a, Date &b)
{
	if (a.year > b.year)
		return -1;
	if (a.year == b.year && a.month > b.month)
		return -1;
	if (a.year == b.year && a.month == b.month && a.day > b.day)
		return -1;
	long daysss = a.remaindays();
	if (a.year < b.year)
	{
		for (int i = a.year+1; i <=b.year; i++)
			if (a.isleap(i))
				daysss += 366;
			else
				daysss += 365;
		daysss -= b.remaindays();
	}
	else if (a.year == b.year)
		daysss = a.remaindays() - b.remaindays();
	else
		daysss= b.day - a.day;
	return daysss;
}
class Student
{
	string name;
	Date born;
	public:
		void set(){cin>>name;born.set();}
		int operator-(Student & other)
		{
			if(CountDay(born,other.born)<0)
			return CountDay(other.born,born);
			return CountDay(born,other.born);
		}
		void show(){cout<<name;}
};
int main()
{
    int n,i,j,max=0,min=0,maxdays=0;
    cin>>n;
    Student * p=NULL;
    p=new Student[n];
    for(i=0;i<n;i++)
    p[i].set();
    for(i=0;i<n-1;i++)
    for(j=i+1;j<n;j++)
    if(abs(p[i]-p[j])>maxdays)
    {
		max=i;
		min=j;
		maxdays=abs(p[i]-p[j]);
	}
    p[max].show();
    cout<<"和";
    p[min].show();
    cout<<"年龄相差最大,为"<<maxdays<<"天。";
}
  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

MaolinYe(叶茂林)

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

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

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

打赏作者

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

抵扣说明:

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

余额充值