日期问题(间隔,星期)

日期问题

这里带来两个日期问题:一是给定两个日期,输出相隔天数;二是给定日期输出星期;最后有一个一的扩展即给出日期输出一年的多少天。

日期间隔问题

输入两个日期如20200129—20191231八位数字字符串。输出两个日期的间隔天数。
日期间隔问题输入输出演示
我采用Buf[]year[month][day]三维数组来存放数组下标(即年月日)对应于原点日期间隔的天数。这是Hash的思想,同时也是解决后面几道题目关键,这里很重要。详细代码如下:

#include<iostream>
using namespace std;

//闰年1 平年0
//能被400整除。或者能被4整除但不能被100整除。
#define isLeapYear(x)   ((x%4 == 0)&&(x%100 != 0))||(x%400 == 0)? 1 : 0

//列举出一年十二个月中的每个月的天数
int monthDay[13][2] = { 
    0,0,
    31,31,
    28,29,
    31,31,
    30,30,
    31,31,
    30,30,
    31,31,
    31,31,
    30,30,
    31,31,
    30,30,
    31,31
};


class twoDate
{
public:
    int year;
    int month;
    int day;

    //从0年1月1日开始计算间隔天数,存放在buf三维数组中
    void getDay()              
    {
        day++;
        if(day > monthDay[month][isLeapYear(year)])
        {
            month ++;   
            day = 1;
        }
        if(month > 12)
        {
            year++;
            month = 1;
        }
    }
};


//求绝对值函数
int abs(int x)
{
    return x<0 ? -x:x;
}


int buf[5001][13][32];

int main()
{
    system("CLS");
    int cnt = 0;
    
    //创建类
    twoDate date;
    date.year = 0;
    date.month = 1;
    date.day = 1;

    //开始计数
    while (date.year != 5001)
    {
        buf[date.year][date.month][date.day] = cnt++;
        date.getDay();
    }
    
    cout<<"Input:"<<endl;
    int y1,y2,m1,m2,d1,d2;
    scanf("%4d%2d%2d",&y1,&m1,&d1);
    scanf("%4d%2d%2d",&y2,&m2,&d2);
    // cin>>y1>>m1>>d1;   
    // cin>>y2>>m2>>d2;

    cout<<"Output:"<<endl;
    cout<<abs(buf[y2][m2][d2]-buf[y1][m1][d1]) + 1<<endl;           //输出两个日期的天数之差
    return 0;
}

日期转换星期问题

这里不知道该取什么名字,就用这个名字代替吧。因为输入的是日期,输出为星期X。
输入输出
与问题一相似的是,仍然采用了Hash的思想存储间隔天数,将字符串转换成数值,从而便于进行%7(算数运算)操作。根据预设的原点日期的星期得出输入日期的星期。

#include<iostream>
#include<string.h>
using namespace std;


//判断闰平年
#define isLeapYear(x) ((x%4 == 0)&&(x%100 != 0))||(x % 400 == 0)?1:0


//每个月份的天数
int monthDay[13][2] = {
    0,0,
    31,31,
    28,29,
    31,31,
    30,30,
    31,31,
    30,30,
    31,31,
    31,31,
    30,30,
    31,31,
    30,30,
    31,31
};

//保存每个月的名字
char monthName[13][15] = {
    "",
    "January",
    "February",
    "March",
    "April",
    "May",
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December"
};

//保存每个星期的名字
char weekName[8][15] = {
    "Sunday",
    "Monday",
    "Tuesday",
    "Wednesday",
    "Thursday",
    "Friday",
    "Saturday"
};

//创建类,存储年月日
class DayOfWeek
{
    public:
        int year;
        int month;
        int day;

        void getDay()
        {
            day ++;
            if(day > monthDay[month][isLeapYear(year)])
            {
                day = 1;
                month ++;
            }
            if(month > 12)
            {
                month = 1;
                year ++;
            }
        }
};

//相对于原点日期1000年1月1日的间隔天数
int Buf[3001][13][32];
void countDay()
{
    int cnt = 0;
    DayOfWeek date;
    date.year = 0;
    date.month = 1;
    date.day = 1;

    while (date.year != 3001)
    {
        Buf[date.year][date.month][date.day] = cnt++;
        date.getDay();
    }
}


//此处无需用到绝对值函数,只需对负数对7取余得到-6 - 0的数后再加7从而再次取余即可
int abs(int x)
{
    return (x < 0) ? -x : x;
}

int main()
{
    system("CLS");
    countDay();
    int y,d;
    int i;
    char m[15];
    scanf("%d%s%d",&d,m,&y);
    for (i = 1; i < 13; i++)
    {
        //判断月份字符与月份字符比对
        if (strcmp(m,monthName[i]) == 0)
        {
            break;
        }
        
    }
    
    cout<<weekName[(((Buf[y][i][d] - Buf[2020][1][26]) % 7) + 7) % 7];
  
    return 0;
}   

拓展:一年第几天问题

本问题是问题一的延伸,输入为一个日期,输出便是一年的第几天。本问题求解思路是:将问题一的原点日期改成,输入年份的1月1日便可。因此这种解法,下面不多讲。我采用的是二维数组Buf[month][day]保存一年的多少天,和问题一相似,三维变二维,最后根据输入的年份判断闰平年即可(getYear成员函数)。

在这里插入图片描述
在这里插入图片描述

#include<iostream>
using namespace std;

//判断闰平年
#define isLeapYear(x)  (((x % 4 == 0)&&(x % 100 != 0))||(x % 400 == 0)) ? 1 : 0

int Monthday[13][2] = {
    0,0,
    31,31,
    28,29,
    31,31,
    30,30,
    31,31,
    30,30,
    31,31,
    31,31,
    30,30,
    31,31,
    30,30,
    31,31
};

class printDay
{
public:
    int year;
    int month;
    int day;

//编写此成员函数的目的是:通过传入参数决定year的值,从而根据isLeapYear()进行闰平年的判断
    void getYear(int y)
    {
        year = y;
    }

    void getDay()
    {
        day++;
        if(day > Monthday[month][isLeapYear(year)])
        {
            day = 1;
            month ++;
        }
    }
};

int Buf[13][32];
void countDay(int y)
{
    printDay date;
    date.month = 1;
    date.day = 1;
    date.getYear(y);        //year的值为输入的值
    int cnt = 1;


    while(date.month != 13 && date.day != 32)
    {
        Buf[date.month][date.day] = cnt++;
        date.getDay();
    }

}

int main()
{
    system("CLS");
    int y,m,d;
    scanf("%4d%2d%2d",&y,&m,&d);
    countDay(y);
    cout<<Buf[m][d];
    return 0;
}

说明

VS Code C++
为了便于对输入位数进行控制采用的scanf而为使用cin,如果有大佬会用cin进行输入位数控制,可以在下面评论指导一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值