前言
本文记录一些有关日期类的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:(友元类)
代码语言:javascript复制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;
使用内部类:
代码语言:javascript复制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
解题思路:
- 先记录给出的
day
. - 根据给出的
year
和month
计算天数 - 将前面每个月的天数累加
day
.
代码实现:
代码语言:javascript复制#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的个数输出。
解题思路:
这只是日期类中的一个接口而已,实现过日期类可以直接复用.
代码实现
代码语言:javascript复制#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-d-dn", _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
代码实现:
代码语言:javascript复制#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("M--", &year1, &month1, &day1);
scanf("M--", &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
代码实现:
代码语言:javascript复制#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("d-d-d",_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;
}
本篇文章只是记录刷题,并没有过多讲解,建议实现一下日期类.