计算xx年xx月xx日是星期几

  代码:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

int hashMapping(int mouth)
{
    vector<int> days{31,28,31,30,31,30,31,31,30,31,30,31};
    return days[mouth - 1];
}

int IsLeapYear(int year, int mouth)
{
    if(((year%4 == 0 && year%100 != 0) || (year%400 == 0)) && mouth == 2)
    {
        return hashMapping(mouth) + 1;
    }
    return hashMapping(mouth);
}

int CalculateDays(int start_year, int end_year, int start_mouth, int end_mouth)
{
    int days = 0;
    if (end_mouth >= start_mouth)
    {
        if (start_year < end_year)
        {
            for (int i = start_year; i < end_year; i++)
            {
                for (int j = start_mouth; j <= 12; j++)
                    days += IsLeapYear(i, j);
                for (int j = 1; j <= end_mouth; j++)
                    days += IsLeapYear(i, j);
            }
        }
        else
        {
            for (int j = start_mouth; j <= end_mouth; j++)
                days += IsLeapYear(start_year, j);
        }
    }
    else
    {
        for (int i = start_year; i < end_year; i++)
        {
            for (int j = start_mouth; j <= 12; j++)
                days += IsLeapYear(i, j);
            for (int j = 1; j <= end_mouth; j++)
                days += IsLeapYear(i, j);
        }
    }

    return days;
}

string hashFunc(int days, int week)
{
    vector<string> str{"星期一","星期二","星期三","星期四","星期五","星期六","星期天"};
    return str[(week - 1 + days%7)%7];
}

void PrintWeek(int start_year, int start_mouth, int start_day, int week, int end_year, int end_mouth, int end_day)
{
    string we;
    int days;
    switch(week)
    {
        case 1:
            days = CalculateDays(start_year, end_year, start_mouth, end_mouth) - (start_day + IsLeapYear(end_year, end_mouth) - end_day);
            we = hashFunc(days, week);
            break;
        case 2:
            days = CalculateDays(start_year, end_year, start_mouth, end_mouth) - (start_day + IsLeapYear(end_year, end_mouth) - end_day);
            we = hashFunc(days, week);
            break;
        case 3:
            days = CalculateDays(start_year, end_year, start_mouth, end_mouth) - (start_day + IsLeapYear(end_year, end_mouth) - end_day);
            we = hashFunc(days, week);
            break;
        case 4:
            days = CalculateDays(start_year, end_year, start_mouth, end_mouth) - (start_day + IsLeapYear(end_year, end_mouth) - end_day);
            we = hashFunc(days, week);
            break;
        case 5:
            days = CalculateDays(start_year, end_year, start_mouth, end_mouth) - (start_day + IsLeapYear(end_year, end_mouth) - end_day);
            we = hashFunc(days, week);
            break;
        case 6:
            days = CalculateDays(start_year, end_year, start_mouth, end_mouth) - (start_day + IsLeapYear(end_year, end_mouth) - end_day);
            we = hashFunc(days, week);
            break;
        case 7:
            days = CalculateDays(start_year, end_year, start_mouth, end_mouth) - (start_day + IsLeapYear(end_year, end_mouth) - end_day);
            we = hashFunc(days, week);
            break;
    }
    cout << start_year << '/' << start_mouth << '/' << start_day <<
        '~' << end_year << '/' << end_mouth << '/' << end_day << " 共有:"
        << days << "天 " << endl;
    cout << end_year << "年" << end_mouth << "月" << end_day << "日是" << we << endl;
}

int main()
{
    int start_year, start_mouth, start_day;
    int end_year, end_mouth, end_day;
    int week;

    cout << "请输入起始年/月/日 以及 星期几:" << endl;
    cin >> start_year;
    cin >> start_mouth;
    cin >> start_day;
    cin >> week;

    cout << "请输入结束年/月/日:" << endl;
    cin >> end_year;
    cin >> end_mouth;
    cin >> end_day;

    PrintWeek(start_year, start_mouth, start_day, week, end_year, end_mouth, end_day);

    return 0;
}

  运行结果:

   第二个版本:直接输入xx年xx月xx日 就可以计算日期为星期几:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

//以 1890/1/1 星期三 为基准

int hashMapping(int mouth)
{
    vector<int> days{31,28,31,30,31,30,31,31,30,31,30,31};
    return days[mouth - 1];
}

int IsLeapYear(int year, int mouth)
{
    if(((year%4 == 0 && year%100 != 0) || (year%400 == 0)) && mouth == 2)
    {
        return hashMapping(mouth) + 1;
    }
    return hashMapping(mouth);
}

int CalculateDays(int year, int mouth)
{
    int days = 0;

    if (1890 < year)
    {
        for (int i = 1890; i < year; i++)
        {
            for (int j = 1; j <= 12; j++)
                days += IsLeapYear(i, j);
        }
        for (int j = 1; j <= mouth; j++)
            days += IsLeapYear(year, j);
    }
    else if(1890 > year)
    {
        for (int j = mouth; j <= 12; j++)
            days += IsLeapYear(year, j);
        for (int i = year + 1; i < 1890; i++)
        {
            for (int j = 1; j <= 12; j++)
                days += IsLeapYear(i, j);
        }
    }
    else
    {
        for (int j = 1; j <= mouth; j++)
            days += IsLeapYear(1890, j);
    }

    return days;
}

string hashFunc(int days)
{
    vector<string> str{"星期一","星期二","星期三","星期四","星期五","星期六","星期天"};
    return str[(2 + days%7)%7]; // 因为是以星期三为基准 所以是下标2
}

void PrintWeek(int year, int mouth, int day)
{
    if ((year > 1889) && (mouth <= 12 && mouth >= 1) && (day <= 31 && day >= 1))
    {
        string we;
        int days = CalculateDays(year, mouth) - (1 + IsLeapYear(year, mouth) - day);
        if (1890 <= year)
            we = hashFunc(days);

        cout << year << "年" << mouth << "月" << day << "日是 " << we << endl;
    }
    else
    {
        cout << "输入有误!" << endl;
        exit(1);
    }
}

int main()
{
    int year, mouth, day;

    cout << "请输入年/月/日:" << endl;
    cin >> year;
    cin >> mouth;
    cin >> day;

    PrintWeek(year, mouth, day);

    return 0;
}

  运行结果:

  特殊的:

  ps:1890/1/1 星期三 我是度娘知道的,所以也可以通过度娘检验我的程序结果的正确性。

  程序不能计算1890年以前的。因为不知道为什么目前算法对往回算不正确。原本我是以2018/1/1 星期一为基准的 但就是发现输入过去的日期算法就不正确后,就尽量往以前的年份改,发现度娘的最早也就能算1890/1/1的,但足够用了,不过如果能将年份尽量处于中间段,往前后算的计算次数就会减少很多,虽然算法时间复杂度还是O(n^2)。

  给个度娘截图:

 

转载于:https://www.cnblogs.com/darkchii/p/8510121.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值