代码:
#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)。
给个度娘截图: