就像标题所说的那样,我试图找出第13届星期五在特定年份出现的次数。我必须使用date
类,并以某种方式编写代码来解决它。
#ifndef DATE_H
#define DATE_H
#include <string>
#include <iostream>
using namespace std;
string Month[] = { "", "January", "February", "March", "April", "May", "June", "July",
"August", "September", "October", "November", "December" };
int daysInMonth[2][13] = { { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } };
string DOW[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "" };
class Date {
private:
int *month;
int *day;
int *year;
public:
// constructors
Date(int month, int day, int year);
Date(); // default constructor
Date(Date &other); // copy constructor
Date(string mmddyyyy); // constructor that takes a string as parameter e.g "10/31/2012"
~Date();
// overload assignment operator
Date & operator=(Date & rhs);
Date & operator++();
Date & operator++(int);
Date & operator--();
Date & operator--(int);
bool operator ==(Date & rhs);
bool operator != (Date & rhs);
bool operator > (Date & rhs);
bool operator < (Date & rhs);
int operator-(Date & rhs);
Date & operator+(int);
// accessors
int getDay() {
return *this->day;
}
int getMonth() {
return *this->month;
}
int getYear() {
return *this->year;
}
static Date toDate(int doy, int yr) {
int dayOfMonth = doy;
int month = 1;
int isleap = isLeap(yr);
for (int i = 1; i < 13; i++) {
int daysThisMonth = daysInMonth[isleap][i];
if (dayOfMonth <= daysThisMonth) {
break;
}
else {
month++;
dayOfMonth -= daysThisMonth;
}
}
return *new Date(month, dayOfMonth, yr);
}
// display date in the format of mm/day/year e.g. 10/31/2012
void display() {
cout << *this->month << "/" << *this->day << "/" << *this->year;
}
// returns true if the given year is a leap year and false otherwise
static int isLeap(int year) {
return ((year % 400 == 0) || (year % 4 == 0 && year % 100 != 0));
}
// returns the day code the the new year day of the given year
static int get_day_code(int year) {
return (year + (year - 1) / 4 - (year - 1) / 100
+ (year - 1) / 400) % 7;
}
// overloading get_day_code that returns the day code of the specific day
static int get_day_code(int year, int month, int day) {
int dayCodeForYear = get_day_code(year);
Date temp(month, day, year);
int doy = temp.dayOfYear() - 1;
int dayCode = (dayCodeForYear + doy) % 7;
return dayCode;
}
int dayOfWeek() { // return the day code of this day
int dayOfYear = this->dayOfYear() - 1;
int firstDayOfTheYear = Date::get_day_code(*this->year);
dayOfYear += firstDayOfTheYear;
return dayOfYear % 7;
}
int dayOfYear() { // returns the day of the year, eg, the day of year for Feb 28 is 59.
int doy = 0;
int isleap = isLeap(*year);
for (int i = 1; i < *month; i++) {
doy += daysInMonth[isleap][i];
}
doy += *day;
return doy;
}
};
Date::Date(int month, int day, int year) {
this->month = new int(month);
this->day = new int(day);
this->year = new int(year);
}
Date::Date() {
this->month = new int(1);
this->day = new int(1);
this->year = new int(2000);
}
Date::Date(Date &other) {
this->month = new int(*(other.month));
this->day = new int(*(other.day));
this->year = new int(*(other.year));
}
Date::Date(string mmddyyyy) {
string mm = mmddyyyy.substr(0, 2);
string dd = mmddyyyy.substr(2, 2);
string yyyy = mmddyyyy.substr(4, 4);
this->month = new int(atoi(mm.c_str()));
this->day = new int(atoi(dd.c_str()));
this->year = new int(atoi(yyyy.c_str()));
}
Date::~Date() {
if (month) delete month;
if (day) delete day;
if (year) delete year;
}
bool Date::operator == (Date & rhs) {
return (*year == *(rhs.year) && *month == *(rhs.month) && *day == *(rhs.day));
}
bool Date::operator != (Date & rhs) {
return !(*this == rhs);
}
bool Date::operator > (Date & rhs) {
if (*year > *(rhs.year)) return true;
else if (*year < *(rhs.year)) return false;
else if (*month > *(rhs.month)) return true;
else if (*month < *(rhs.month)) return false;
else if (*day > *(rhs.day)) return true;
return false;
}
bool Date::operator < (Date & rhs) {
if (*year < *(rhs.year)) return true;
else if (*year > *(rhs.year)) return false;
else if (*month < *(rhs.month)) return true;
else if (*month > *(rhs.month)) return false;
else if (*day < *(rhs.day)) return true;
return false;
}
Date & Date::operator=(Date & rhs) {
*this->month = *rhs.month;
*this->day = *rhs.day;
*this->year = *rhs.year;
return *this;
}
Date & Date::operator++() {
Date tmp = *this + 1;
*this->month = *tmp.month;
*this->day = *tmp.day;
*this->year = *tmp.year;
return *this;
}
Date & Date::operator++(int) {
Date tmp = *this + 1;
Date * output = new Date(tmp);
*this->month = *tmp.month;
*this->day = *tmp.day;
*this->year = *tmp.year;
return *output;
}
Date & Date::operator--() {
Date tmp = *this + -1;
*this->month = *tmp.month;
*this->day = *tmp.day;
*this->year = *tmp.year;
return *this;
}
Date & Date::operator--(int) {
Date tmp = *this + -1;
Date * output = new Date(tmp);
*this->month = *tmp.month;
*this->day = *tmp.day;
*this->year = *tmp.year;
return *output;
}
int Date::operator-(Date & rhs) {
int yearsDiff = *this->year - *rhs.year;
int daysDiff = this->dayOfYear() - rhs.dayOfYear();
daysDiff += yearsDiff * 365;
return daysDiff;
}
Date & Date::operator+(int) {
int n = 0;
int doy = dayOfYear();
int newDoy = doy + n;
int yearsDiff = newDoy / 365;
newDoy = newDoy % 365;
int newYear = *this->year + yearsDiff;
Date newDate = Date::toDate(newDoy, newYear);
return *new Date(newDate);
}
#endif
这是我一直在搞乱的代码:
#include <iostream>
#include <iomanip>
#include "Date.h"
using namespace std;
void iterateMonth(int);
bool isFriday13th();
string dayofweek[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "" };
string month[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" };
//int dayInMonth[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
//int dayInMonthLeap[13] = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
void iterateMonth(int year) {
int dayCode, month, daysInMonth, day, u;
bool leapYear;
cout << year;
// returns the day on which January 1 of year begins.
dayCode = Date::getDayCode(year);
// returns true if year is a leap year, false otherwise
leapYear = Date::isLeap(year);
// month is 0 for Jan, 1 for Feb, etc.
for (month = 1; month <= 12; month++)
{
switch (month)
{
case 1:
cout << "\n\nJanuary\n";
daysInMonth = 31;
break;
case 2:
cout << "\n\nFebruary\n";
if (leapYear)
daysInMonth = 29;
else
daysInMonth = 28;
break;
case 3:
cout << "\n\nMarch\n";
daysInMonth = 31;
break;
case 4:
cout << "\n\nApril\n";
daysInMonth = 30;
break;
case 5:
cout << "\n\nMay\n";
daysInMonth = 31;
break;
case 6:
cout << "\n\nJune\n";
daysInMonth = 30;
break;
case 7:
cout << "\n\nJuly\n";
daysInMonth = 31;
break;
case 8:
cout << "\n\nAugust\n";
daysInMonth = 31;
break;
case 9:
cout << "\n\nSeptember\n";
daysInMonth = 30;
break;
case 10:
cout << "\n\nOctober\n";
daysInMonth = 31;
break;
case 11:
cout << "\n\nNovember\n";
daysInMonth = 30;
break;
case 12:
cout << "\n\nDecember\n";
daysInMonth = 31;
break;
}
//cout << "\n\nSun Mon Tue Wed Thu Fri Sat\n";
for (int i = 0; i < (sizeof(dayofweek) / sizeof(dayofweek[0])); i++)
{
cout << dayofweek[i] << " ";
}
cout << endl;
for (day = 1; day <= dayCode * 5; day++)
{
cout << " ";
}
for (day = 1; day <= daysInMonth; day++)
{
cout << setw(3) << day;
if ((day + dayCode) % 7 > 0)
{
cout << " ";
}
else
cout << endl;
}
dayCode = (dayCode + daysInMonth) % 7;
}
}
//bool isFriday13th() {
//
//}
int main() {
int year;
//cout << "Please enter a year: ";
cout << "Final ";
cin >> year;
iterateMonth(year);
}
我从某人那里得到的一个想法是在1月13日创建一个Date
对象,使用dayOfWeek
方法检查是否是星期五,如果没有,则递增直到我到达星期五,然后跳到前方7并使用getDay
检查它是否为13.我用这个尝试了这个:
Date tmp(1, 13, year);
int dc = tmp.dayOfWeek(); // return day code
tmp.display();
cout << endl;
++tmp;
tmp.display();
cout << endl;
我预计tmp.display();
行显示2013年1月13日(将2013年作为年份),它确实如此,但++tmp
行给出了相同的结果。我还以为我必须以某种方式找到与星期五相对应的日期代码(现在dc
为0),但我无法弄明白。
此外,另一篇与同一问题有关的帖子说,每个星期日开始的月份都会在星期五13号,所以我试着想一想如何实现这个。也许在第一个for
循环(switch
语句之上)的某处,我可以检查if (firstDay = Sunday) { cout << "Friday13th exists in " << month << endl; }
那是一种可怕的伪代码,但这是我的想法。有人有想法吗?任何帮助将不胜感激,并提前感谢您。
答案 0 :(得分:3)
嗯......对于初学者 - 如果您使用Date
标题和functions包含在内,<ctime>
课程会更容易。
其次 - 你有一个重载函数:int get_day_code(int year, int month, int day)
。如果它做了它应该做的事情(或更像是:描述的内容),为了检查一年中第13次星期五的次数,你可能会这样做:
int howManyFridays = 0;
for(int i=0;i<12;i++)
if(get_day_code(year,i,13)==CODE_FOR_FRIDAY) howManyFridays++;
return howManyFridays;
答案 1 :(得分:2)
你可以这样做,而无需对一年中某一天的函数进行大量调用。如果你知道1月份第一个星期天的日期,那就没什么了不起的。只是一些基本的数学。
2013年,1月的第一个星期日是第6个星期日。所以13日是星期天。我们知道,如果1月的第一个星期日是第6个,那么2月的第一个星期日就是第3个星期日。为13日增加10天。那是星期三。
我怎么知道二月的第一个星期天是第三个?因为这就是日历的工作方式。如果您参加1月份第一个星期天的日期,请添加4和mod 7,这将为您提供2月份第一个星期日的日期。日历是固定的;在1月的第一个星期日,您可以使用模7算法轻松计算任意月份的第一个星期日。
补偿是:
Normal Year: 0 4 4 1 6 3 1 5 2 0 4 2
Leap Year: 0 4 3 0 5 2 0 4 1 6 3 1
如果你想知道星期五在13日的几个月,那么下一个星期日是15日,这意味着该月的第一个星期日必须是第一个星期日。
根据上表,如果1月的第一个星期日是第1个星期,那么在正常年份,你将在星期五13日:1月和10月有两个月。如果是闰年,那么你将有1月,4月和7月。今年的第一个星期天是第6个星期日,所以你需要几个月的偏差为2个。所以9月和12月。
如果月份偏移量加上1月份第一个星期日的日期等于8,则该月份的星期五为13日。
我前段时间用这个作为记忆法。有关详细说明,请参阅Now what day is that?。