前言
本文记录一些有关日期类的oj题题解,实现过日期类小项目的可以练一下手,本文不做过多讲解.
一、求1+2+3+…+n
题目来源于:牛客
题目链接:传送门
题目介绍:
求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
示例1:
输入:5 返回值:15
示例2:
输入:1 返回值:1
解题思路:
利用每次创建对象会自动调用构造函数,创建两个静态成员变量.
变量1:count每次调用构造函数后+1.
变量2:sum记录每次cout相加的结果.
创建一个大小为n的对象数组,这样就会创建n个对象,调用n次构造函数.
代码实现:
写法1:(友元类)
class small_Solution{ public: friend class Solution; small_Solution() { count++; sum+=count; } private: static int count; static int sum; }; class Solution { public: int Sum_Solution(int n) { small_Solution a[n]; return small_Solution::sum; } }; int small_Solution::count=0; int small_Solution::sum=0;
使用内部类:
class Solution { public: int Sum_Solution(int n) { small_Solution a[n]; return Solution::sum; } class small_Solution{//内部类 public: small_Solution() { //内部类是外部类的天生友元,可直接使用外部类的静态成员变量 count++; sum+=count; } }; private: static int count; static int sum; }; int Solution::count=0; int Solution::sum=0;
二、计算日期到天数转换
题目来源于:牛客网
题目链接:传送门
题目介绍:
根据输入的日期,计算是这一年的第几天。
保证年份为4位数且日期合法。
输入描述:
输入一行,每行空格分割,分别是年,月,日
输出描述:
输出是这一年的第几天
示例1
输入:2012 12 31 输出:366
示例2
输入:1982 3 4 输出:63
解题思路:
1.先记录给出的day.
2.根据给出的year和month计算天数
3.将前面每个月的天数累加+day.
代码实现:
#include <iostream> using namespace std; int is_leap_year(int year) { if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) { return 1; } else return 0; } int main() { int year = 0, moon = 0, day = 0; cin>>year>>moon>>day; int sum = day; int leap = is_leap_year(year);//判断是否是闰年 int arr[13] = { 0,31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; for (int i = 1; i < moon; i++) { sum += arr[i]; if (i == 3 && leap == 1) { sum += 1; } } cout<<sum; return 0; }
三、日期累加
题目来源于:牛客
题目链接:传送门
题目介绍:
设计一个程序能计算一个日期加上若干天后是什么日期。
输入描述:
输入第一行表示样例个数m,接下来m行每行四个整数分别表示年月日和累加的天数。
输出描述:
输出m行,每行按yyyy-mm-dd的个数输出。
解题思路:
这只是日期类中的一个接口而已,实现过日期类可以直接复用.
代码实现
#include <iostream> using std::cin; using std::cout; using std::endl; class Date { public: // 全缺省的构造函数 Date(int year=2023, int month=1, int day=1) { _year = year; _month = month; _day = day; } // 获取某年某月的天数 int GetMonthDay(int year, int month) { int day[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)) { //如果是闰年,且是2月 day[2] = 29; } return day[month]; } //打印日期类函数 void Print() { printf("%d-%02d-%02d\n", _year, _month, _day); } // 日期+=天数 Date& operator+=(int day) { if (day < 0) { return *this -= -day;//调用"-="的运算符重载 } _day += day; while (_day > GetMonthDay(_year, _month)) { //如果超过当月天数 _day -= GetMonthDay(_year, _month); _month++; if (_month > 12) { _month = 1; _year++; } } return *this; } Date& operator-=(int day) { if (day < 0) { return *this += -day;//调用"+="的运算符重载 } _day -= day; while (_day <= 0) { //如果是负数 _month--; if (_month <= 0) { _month = 12; _year--; } _day += GetMonthDay(_year, _month); } return *this; } private: int _year; int _month; int _day; }; int main() { int num=0; cin>>num; while(num--) { int year=0,month=0,day=0,n=0; cin>>year>>month>>day>>n; Date d1(year,month,day); d1+=n; d1.Print(); } return 0; }
四、日期差值
题目来源于:牛客
题目链接:传送门
题目介绍
有两个日期,求两个日期之间的天数,如果两个日期是连续的我们规定他们之间的天数为两天
输入描述:
有多组数据,每组数据有两行,分别表示两个日期,形式为YYYYMMDD
输出描述:
每组数据输出一行,即日期差值
示例:
输入:
20110412 20110422
输出:
11
代码实现:
#include <iostream> using namespace std; class Date { public: //Date.cpp Date(int year, int month, int day) { _year = year; _month = month; _day = day; } int GetMonthDay(int year, int month) { int day[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)) { //如果是闰年,且是2月 day[2] = 29; } return day[month]; } bool operator>(const Date& d) { if (_year > d._year) { //如果年大 return true; } { if (_year == d._year) { if (_month > d._month) { //年相同,月大 return true; } else { if (_day > d._day) { //入如果年月相同,日大 return true; } return false;//月小,或者日小和相等 } } return false;//如果年小 } } // 日期-日期 返回天数 int operator-(const Date& d) { //小的日期一直++,加到和大的日期一样时,加了多少次就差多少天 Date max = *this; Date min = d; int flag = 1; int n = 0; while (min != max) { //用n统计相差多少天 ++min; ++n; } return n * flag; } // 前置++ Date& operator++() { _day += 1; while (_day > GetMonthDay(_year, _month)) { //如果超过当月天数 _day -= GetMonthDay(_year, _month);//则减去当月的天数 //月份向后推一个月 _month++; if (_month > 12) { _month = 1; _year++; } } return *this; } bool operator==(const Date& d) { if (_year == d._year && _month == d._month && _day == d._day ) { return true; } return false; } // !=运算符重载 bool operator != (const Date& d) { return !(*this == d); } private: int _year; int _month; int _day; }; int main() { int year1 = 0, month1 = 0, day1 = 0; int year2 = 0, month2 = 0, day2 = 0; scanf("%4d%2d%2d", &year1, &month1, &day1); scanf("%4d%2d%2d", &year2, &month2, &day2); Date d1(year1, month1, day1); Date d2(year2, month2, day2); int ret = 0; if (d1 > d2) { ret = d1 - d2; } else { ret = d2 - d1; } cout<<ret+1; return 0; }
五、打印日期
题目来源于:力扣
题目链接:传送门
题目介绍
给出年分m和一年中的第n天,算出第n天是几月几号。
输入描述:
输入包括两个整数y(1<=y<=3000),n(1<=n<=366)。
输出描述:
可能有多组测试数据,对于每组数据, 按 yyyy-mm-dd的格式将输入中对应的日期打印出来。
示例:
输入:
2000 3 2000 31 2000 40 2000 60 2000 61 2001 60
输出:
2000-01-03 2000-01-31 2000-02-09 2000-02-29 2000-03-01 2001-03-01
代码实现:
#include <iostream> using namespace std; class Date { public: //Date.cpp Date(int year=2023 , int month=1, int day=0) { _year = year; _month = month; _day = day; //这里也就体现出了,成员变量前面'_'的好处,方便与参数区分 } int GetMonthDay(int year, int month) { int day[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))//如果是闰年,且是2月 { day[2] = 29; } return day[month]; } // 日期+=天数 Date& operator+=(int day) { _day += day; while (_day > GetMonthDay(_year, _month))//如果超过当月天数 { _day -= GetMonthDay(_year, _month);//通过调用GetMonthDay函数获取当月天数 _month++; if (_month > 12)//月数超过12,则开始下一年 { _month = 1; _year++; } } return *this; } void print() { printf("%04d-%02d-%02d",_year,_month,_day); } private: int _year; int _month; int _day; }; int main() { int year=0,month=0,day=0; while(scanf("%d%d",&year,&day)==2) { Date d1(year); d1+=day; d1.print(); cout<<endl; } return 0; }
本篇文章只是记录刷题,并没有过多讲解,建议实现一下日期类.