7-4 日期之差 (25 分)
给定两个日期,请你计算这两个日期之间有少天(定义连续的日期之差为2天)
输入格式:
共两行,每一行输入一个日期,日期格式为yyyy-MM-dd
输出格式:
一个正整数,为两个日期之间的差
输入样例:
2021-07-02
2021-07-15
输出样例:
14
解题思路:
看一眼题目没想着啥巧妙技巧,用暴力法准没错。
1.读入数据
首先利用整型数组存放平年每个月的天数信息,而正好空出来的位置 monthday[0] 用来存放平年一年的总天数365天,遇到闰年的情况再特殊处理就好了。
int monthday[] = { 365,31,28,31,30,31,30,31,31,30,31,30,31 };
读入数据用到了 cin.ignore() 函数,目的是为了跳过输入数据中的符号“-”。或者用一个char类型变量来接收这个多余的符号也是可以的。
int y1, y2, m1, m2, d1, d2;
cin >> y1;
cin.ignore(1);
cin >> m1;
cin.ignore(1);
cin >> d1;
cin >> y2;
cin.ignore(1);
cin >> m2;
cin.ignore(1);
cin >> d2;
2.数据检验
默认是第一个给出的时间早于第二个给出的时间,但第五个测试点数据为第一个时间点晚于第二个时间点,故还需要数据合理性检验。这里用到了 swap() 函数,目的是把两个数据类型的值交换。
bool Is_Legal = true; //数据检查
if (y1 > y2)
{
Is_Legal = false;
}
else if (y1 == y2)
{
if (m1 > m2)
{
Is_Legal = false;
}
else if (m1 == m2)
{
if (d1 > d2)
{
Is_Legal == false;
}
}
}
if (!Is_Legal) //第二个时间小于第一个年份时间
{
swap(y1, y2); //把两组数据交换
swap(m1, m2);
swap(d1, d2);
}
3.计算天数
首先先写一个函数,用来计算某月某日是这一年的第几天。
int Days_Year(int year, int month, int day) { //计算year/month/day是这一年的第几天
int days = 0;
for (int i = 1; i < month; i++)
{
days += monday[i];
}
if (Is_Runnian(year) && month > 2) //闰年而且月份大于2月时才加一
{
days++;
}
days += day;
return days;
}
分两种情况,年份不相等和相等。
int ret = 0; //相差总天数
if (y1 != y2) //年份不相等
{
if (Is_Runnian(y1)) //y1年剩余的天数加上y2年m2月d2的天数
{
ret += (366 - Days_Year(y1, m1, d1)) + Days_Year(y2, m2, d2) + 1;
}
else
{
ret += (365 - Days_Year(y1, m1, d1)) + Days_Year(y2, m2, d2) + 1;
}
for (int i = y1 + 1; i < y2; i++) //从y1+1开始,既从y1+1到y2(不包括y2)年中,隔了几年
{
ret += monday[0];
if (Is_Runnian(i)) //闰年就多加一天
{
ret++;
}
}
}
else //年份相等
{
ret = Days_Year(y2, m2, d2) - Days_Year(y1, m1, d1) + 1; //别忘记加一喔
}
完整代码
如下所示:
#include<iostream>
using namespace std;
int monday[] = { 365,31,28,31,30,31,30,31,31,30,31,30,31 };
bool Is_Runnian(int y) {
if ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0)
{
return true;
}
return false;
}
int Days_Year(int year, int month, int day) { //计算year/month/day是这一年的第几天
int days = 0;
for (int i = 1; i < month; i++)
{
days += monday[i];
}
if (Is_Runnian(year) && month > 2)
{
days++;
}
days += day;
return days;
}
int main()
{
int y1, y2, m1, m2, d1, d2;
cin >> y1;
cin.ignore(1);
cin >> m1;
cin.ignore(1);
cin >> d1;
cin >> y2;
cin.ignore(1);
cin >> m2;
cin.ignore(1);
cin >> d2;
bool Is_Legal = true;
if (y1 > y2)
{
Is_Legal = false;
}
else if (y1 == y2)
{
if (m1 > m2)
{
Is_Legal = false;
}
else if (m1 == m2)
{
if (d1 > d2)
{
Is_Legal == false;
}
}
}
if (!Is_Legal) //第二个时间小于第一个年份时间
{
swap(y1, y2); //把两组数据交换
swap(m1, m2);
swap(d1, d2);
}
int ret = 0; //相差总天数
if (y1 != y2) //年份不相等
{
if (Is_Runnian(y1)) //y1年剩余的天数加上y2年m2月d2的天数
{
ret += (366 - Days_Year(y1, m1, d1)) + Days_Year(y2, m2, d2) + 1;
}
else
{
ret += (365 - Days_Year(y1, m1, d1)) + Days_Year(y2, m2, d2) + 1;
}
for (int i = y1 + 1; i < y2; i++) //从y1+1开始,既从y1+1到y2(不包括y2)年中,隔了几年
{
ret += monday[0];
if (Is_Runnian(i)) //闰年就多加一天
{
ret++;
}
}
}
else //年份相等
{
ret = Days_Year(y2, m2, d2) - Days_Year(y1, m1, d1) + 1; //别忘记加一喔
}
cout << ret << endl;
}
总结:
测试点全部通过。写题时还是不能理所当然地认为输入格式一定会保证正确,最好多留个心眼。如果刷题时发现有的测试点一直通不过,可以看看是不是没有做数据检验。