当前位置: 首页> 游戏> 攻略 > 日期类-刷题部分

日期类-刷题部分

时间:2025/7/12 6:28:51来源:https://blog.csdn.net/2301_81205182/article/details/141894185 浏览次数:0次

日期类刷题(代码题)

  • 一、计算日期差值
    • 题目链接
    • 题目描述:
  • 二、计算一年的第几天
    • 题目链接:
    • 题目描述:
  • 三、求阶乘
    • 题目链接
    • 题目描述
  • 四、累加天数
    • 题目链接
    • 题目描述
  • 五、打印日期
    • 题目链接
    • 题目描述
  • 总结

我会给出题目链接,大家可以看完题目自己先尝试写一下,再来看解析。

一、计算日期差值

题目链接

https://www.nowcoder.com/practice/ccb7383c76fc48d2bbc27a2a6319631c?tpId=62&&tqId=29468&rp=1&ru=

题目描述:

在这里插入图片描述
两个日期之前的天数有两种算法,这个在我们之前日期类里也讲过,
第一种思路:
在这里插入图片描述
第二种思路:小的日期加加,直到加到大的日期,加加的次数就是相差的天数,需要注意的两个点是1、这里规定相邻的日期为两天,我们之前的算法是相邻两天为一天,所以最后的结果还要加1;2、输入的形式是将8个数字连续输入的,我们怎么将其中的年月日给取出来这也是一个小问题。

我们c++类中(续)里的日期类它的操作我们用不完,我们只需要写我们需要的:

#include <climits>
#include <iostream>
using namespace std;class Date
{
public:int getMonthDay(int year, int month){int MonthDay[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };if ((month == 2) && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0))return 29;elsereturn MonthDay[month];}Date(int year = 1, int month = 1, int day = 1) :_year(year),_month(month),_day(day){}bool operator>(const Date& d);bool operator<(const Date& d);bool operator==(const Date& d);Date& operator+=(int day);int operator-(const Date& d);
private:int _year;int _month;int _day;
};
Date& Date::operator+=(int day)
{_day += day;while (_day > getMonthDay(_year, _month)){_day -= getMonthDay(_year, _month);_month++;if (_month == 13){_year++;_month = 1;}}return *this;
}
bool Date::operator>(const Date& d)
{return !(*this == d) && !(*this < d);
}
bool Date::operator<(const Date& d)
{if (_year < d._year){return true;}else if (_year == d._year){if (_month < d._month){return true;}else if (_month == d._month){return _day < d._day;}}return false;
}
bool Date::operator==(const Date& d)
{return _year == d._year &&_month == d._month &&_day == d._day;
}
int Date::operator-(const Date& d)
{Date max = *this > d ? *this : d;//不管谁大,我们的max选出的一定大Date min = *this < d ? *this : d;//不管谁小,我们选出的min一定小int count = 0;while (!(min == max)){min += 1;//我们日期类里用的前置和后置++,但这里+=1符合逻辑,就不多写了count++;}return count;
}
int main() {int year = 0, month = 0, day = 0;scanf("%4d%2d%2d", &year, &month, &day);//%4d是将读取到的一串数字前4个作为第一个变量的值,后面同理。Date d(year, month, day);int year1 = 0, month1 = 0, day1 = 0;scanf("%4d%2d%2d", &year1, &month1, &day1);Date d1(year1, month1, day1);cout << d - d1 + 1;//+1是为了符合题目的逻辑return 0;
}

大家看我们采用%4d%2d这种方式来解决输入一串整数会非常的舒服,如果我们不采用这种方式的话,我们也可以使用字符数组的形式,然后我们再从数组中来取,不过这样代码量就会增加。

虽然我们不讲第一种算法,但我也可以让大家看看代码自己思考一下

#include <iostream>
#include <cstdio>
#include <cmath>int GetMonthDay(int year, int month) {int Month[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)) {return 29;}return Month[month];
}int main() {int year, month, day;int year1, month1, day1;scanf("%4d%2d%2d", &year, &month, &day);scanf("%4d%2d%2d", &year1, &month1, &day1);// 确保第一个日期是较早的日期if (year > year1 || (year == year1 && month > month1) || (year == year1 && month == month1 && day > day1)) {std::swap(year, year1);std::swap(month, month1);std::swap(day, day1);}int totalDays = 0;// 处理年份之间的天数for (int i = year; i < year1; i++) {if ((i % 4 == 0 && i % 100 != 0) || i % 400 == 0) {totalDays += 366;} else {totalDays += 365;}}// 处理年份内月份的天数for (int i = 1; i < month1; i++) {totalDays += GetMonthDay(year1, i);}totalDays += day1;for (int i = 1; i < month; i++) {totalDays -= GetMonthDay(year, i);}totalDays -= day;printf("%d", totalDays + 1);return 0;
}

这一种算法的话也是比较容易理解的,并且代码量更少一些,大家可以自己选择,但尽量掌握第一种,

二、计算一年的第几天

题目链接:

https://www.nowcoder.com/practice/769d45d455fe40b385ba32f97e7bcded?tpId=37&&tqId=21296&rp=1&ru=/activity/oj&qru=/ta/huawei/question-ranking

题目描述:

在这里插入图片描述
这一道题也有三种思路:
(1)第一种方式当前日期减减,一直减到该年份的1月1日,减减的次数就是该日期在一年中的哪一天。
(2)第二种方式就反过来,用改年份的1月1日加加,一直加到该日期,加加的次数就是改年的第多少天。
(3)第三种方式我们甚至可以计算当前日期加加,一直加到下一年的1月1日,然后用改年的整年天数减去加加的次数,这一种方式纯属凑思路,大家看看就行。
(4)上面的加加还是太累了,需要我们写日期类,以及日期类里的各种函数,我们不想用,最后一种方法就更简单了,思路是什么呢?
我们不是要计算该日期在一年中的第几天嘛,那我们就将当前月份之前的月份的天数相加,最后再加上我们该日期中的号数不就ok了嘛。

实际前三种思路非常的相似,在日期类里也完成过,所以我们来尝试着写第4中最简单的。

#include <iostream>
using namespace std;int getMonthDay(int year, int month)
{int MonthDay[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))return 29;elsereturn MonthDay[month];
}//还是需要这个函数,因为我们要将前month-1月的天数相加
int main()
{int _year = 0, _month = 0, _day = 0;scanf("%d%d%d", &_year, &_month, &_day);if (_month == 1){printf("%d", _day);//如果输入的是一月我们还需要计算吗?//直接就输出天就行了}else{int day = 0;int m = 1;while (m != _month){day += getMonthDay(_year, m);m++;}printf("%d ", day + _day);//最后再加上号数就OK了}
}

这道题对于我们来说也非常的easy。

三、求阶乘

题目链接

https://www.nowcoder.com/practice/7a0da8fc483247ff8800059e12d7caf1?tpId=13&tqId=11200&tPage=3&rp=3&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

题目描述

在这里插入图片描述
这道题是我们写日期类里的原题,既然我们又遇到了,那我们就再简单说下:
这道题需要注意不能使用乘除法(防止我们用公式法)、禁止使用for、if,case等语句(防止我们使用switch,case这种方式),禁止使用判断语句(防止我们使用递归),大家看这道题有意思吧,把我们常用的全部禁止,所以我们基本只能采用类的方式解决。

那怎么使用类来解决呢?我们之前学习过程中不是学过类在实例化对象的过程会调用构造函数,那我们定义一个n个空间的数组,那我们的构造函数就被执行了n次,我们再定义一个静态的类的成员i,每执行一次构造函数i++,然后将所有的i值加起来就是我们所求的结果,上一节我们也讲过类内类,这里我们类外类与类内类都给大家写一遍。
类外类

#include <regex>
class Sum
{
public:Sum(){_sum += _i;_i++;}static int getsum(){return _sum;}
private:static int _i;static int _sum;
};
int Sum::_i = 1;
int Sum::_sum = 0;
class Solution {
public:int Sum_Solution(int n) {Sum arr[n];//这里使用了变长数组,在这个题目里可以使用,某些编译器无法使用return Sum::getsum();}
};

类内类:

#include <regex>
class Solution {
public:int Sum_Solution(int n) {Sum arr[n];return _sum;}
private:static int _i;static int _sum;class Sum{public:Sum(){_sum += _i;_i++;}};
};
int Solution::_i = 1;
int Solution::_sum = 0;

如果对这块的静态成员变量为什么能够实现有疑惑,大家可以看一下我的上一篇博客–类(下)。

四、累加天数

题目链接

https://www.nowcoder.com/practice/eebb2983b7bf40408a1360efb33f9e5d?tpId=40&&tqId=31013&rp=1&ru=/activity/oj&qru=/ta/kaoyan/question-ranking

题目描述

在这里插入图片描述
这一道题也是非常的简单,但这道题有一个坑,就是最后输出的时候月份和号数小于10,就会在前面补0,前面的逻辑与前面的题一样直接加加100次就行。
那大家看我是怎么解决的:

#include <climits>
#include <iostream>
using namespace std;
class Date
{
private:int _year;int _month;int _day;
public:Date(int year, int month, int day) :_year(year), _month(month), _day(day){}int GetMonthDay(int year, int month){int MonthDay[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))return 29;elsereturn MonthDay[month];}Date& operator+=(int day);int getyear(){return _year;}int getmonth(){return _month;}int getday(){return _day;}
};
Date& Date::operator+=(int day)
{_day += day;while (_day > GetMonthDay(_year, _month)){_day -= GetMonthDay(_year, _month);_month++;if (_month == 13){_year++;_month = 1;}}return *this;
}
void getDate(int year, int day)
{Date d(year, 1, 1);int count = 1;while (count++ != day){d += 1;}printf("%d-%02d-%02d", d.getyear(), d.getmonth(), d.getday());
}
int main() {int year = 0, day = 0;cin >> year >> day;getDate(year, day);
}

这里我使用printf来解决,大家需要知道%2d就是打印两位整数,如果不足两位,左边就空着,我们在前面加0,如果不足就会将0补上,如果位数足够就打印原来的。
这一个小的知识点大家可以记住。

当然了如果记不住怎么办,那也有笨的办法嘛:

if(d.getmonth()<10&&d.getday()<10)printf("%d-0%d-0%d\n",d.getyear(),d.getmonth(),d.getday());else if(d.getday()<10)printf("%d-%d-0%d\n",d.getyear(),d.getmonth(),d.getday());else if(d.getmonth()<10)printf("%d-0%d-%d\n",d.getyear(),d.getmonth(),d.getday());elseprintf("%d-%d-%d\n",d.getyear(),d.getmonth(),d.getday());

这种方式可以是可以但是大家觉得很low对吧!

五、打印日期

题目链接

https://www.nowcoder.com/practice/b1f7a77416194fd3abd63737cdfcf82b?tpId=69&&tqId=29669&rp=1&ru=/activity/oj&qru=/ta/hust-kaoyan/question-ranking

题目描述

在这里插入图片描述
最后一道题我们称之为奖励题,就是很简单对吧。

#include <climits>
#include <iostream>
using namespace std;
class Date
{
private:int _year;int _month;int _day;
public:Date(int year, int month, int day) :_year(year),_month(month),_day(day){}Date& operator+=(int day);int GetMonthDay(int year, int month){int MonthDay[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))return 29;elsereturn MonthDay[month];}int getyear(){return _year;}int getmonth(){return _month;}int getday(){return _day;}
};
Date& Date::operator+=(int day)
{_day += day;while (_day > GetMonthDay(_year, _month)){_day -= GetMonthDay(_year, _month);_month++;if (_month == 13){_month = 1;_year++;}}return *this;
}
int main()
{int n = 0;cin >> n;while (n--){int year = 0, month = 0, day = 0, _day = 0;cin >> year >> month >> day >> _day;Date d(year, month, day);d += _day;printf("%d-%02d-%02d\n",d.getyear(),d.getmonth(),d.getday());}
}

我们之前不是学过加等吗,这道题一个+=就直接搞定,当然大家有别的思路也可以自己尝试。

总结

最后我们总结一下:这一部分的题目完全是为了我们能够熟练使用类中各种运算符重载,以及锻炼我们一个问题多种解决办法的思维,所以大家在做题的过程中可以尽可能得使用多种方式来解决我们的问题,同时这一块代码量的积累也为后面的模版打基础。

关键字:日期类-刷题部分

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: