这是一项练习;我禁止使用C ++的内置日期功能或任何现成的库。
我有这段代码:
#include <iostream>
#include <vector>
using namespace std;
bool IsLeap(unsigned int year)
{
if (year % 4 != 0) return false;
else
if (year % 100 != 0) return true;
else
if (year % 400 != 0) return false;
else
return true;
}
class Date
{
public:
unsigned short int Day;
unsigned short int Month;
unsigned short int Year;
unsigned short int DayOfWeek;
};
int MonthLimit(int Month, int year)
{
switch (Month)
{
case 4:
case 6:
case 9:
case 11:
{
return 30;
break;
}
case 1:
case 3:
case 5:
case 7:
case 8:
case 12:
{
return 31;
break;
}
case 2:
if (IsLeap(year))
{
return 29;
break;
}
else
{
return 28;
break;
}
}
}
const Date FirstDayEver = { 1, 1, 1900, 1 }; //January 1, 1900 was on a Monday.
int main()
{
unsigned int years;
cin >> years;
vector<int> counters(7); //whenever a 13th falls on a day X, we increment the Xth counter. It's that simple
for (Date i = FirstDayEver; !((i.Day == 31) && (i.Month == 12) && (i.Year == 1900 + years - 1)); i.Day++)
{
i.DayOfWeek = (i.DayOfWeek + 1) % 7;
if (i.Month == MonthLimit(i.Month, i.Year))
{
i.Month++;
i.Day = 1;
cout << "Proceeded to " << i.Day << "." << i.Month << "." << i.Year << "\n";
}
if ((i.Day == 31) && (i.Month == 12))
{
i.Year++;
i.Day = 1;
i.Month = 1;
cout << "Proceeded to " << i.Day << "." << i.Month << "." << i.Year << "\n";
}
if (i.Day == 13)
{
counters[i.DayOfWeek]++;
cout << i.Day << "." << i.Month << "." << i.Year << " was a " << i.DayOfWeek << "\n";
}
}
cout << counters[6] << " " << counters[7] << " " << counters[1] << " " << counters[2] << " " << counters[3] << " " << counters[4] << " " << counters[5] << "\n";
exit(0);
}
调试信息(cout
s)用于查看循环中是否发生任何事情。
到目前为止,唯一发生的事情是很多线路说&#34; 13.1.1900是&#34;数量不一。
我认为增加日期的理想逻辑在代码中是相当清楚的,但我试图增加错误。
哪里是我的错?
答案 0 :(得分:1)
首先,
if (i.Month == MonthLimit(i.Month, i.Year))
将月份与月份中的天数进行比较 由于第一个月是1,而那个月有31天,因此您永远不会增加月份 由于你永远不会增加月份,你永远不会增加年份 (如果你已经命名了函数&#34; DaysInMonth&#34;或者其他更清楚它返回的东西,你可能会发现这更容易。)
你想要
if (i.Day == MonthLimit(i.Month, i.Year))
其次,MonthLimit
缺少10月的案例。
答案 1 :(得分:1)
您的增量程序太复杂了 我实际上还在努力弄清楚它们是如何组合在一起的(边缘情况等),但似乎你试图独立地每天/每月/每年进行。
你可以在这样一个简单的函数中完成所有的递增:
void increment_Date(Date &d)
{
d.DayOfWeek = (d.DayOfWeek + 1) % 7; //increase weekday
if (++d.Day > MonthLimit(d.Month, d.Year)//increase day, if larger than month size...
{
d.Day = 1; //reset day to 1
if (++d.Month > 12) //increase month, if larger than year size
{
d.Month = 1; //reset month to 1
d.Year++; //increase year
}
}
}
逻辑更简单,因为我以一种与你似乎完全不同的方式接近它 在上面的函数中,我首先增加最小单位(天),检查溢出,然后在需要时移动到月(等等)。
这种方式的工作原理与汽车里程拨号的数字仅在拨号到达10
并且返回0时才会打勾。或者,添加1到9和&# 39;溢出&#39;进入数字的10位数。
否则你的代码很好。 MonthLimit
的Switch语句是一个不错的选择。
我在函数中添加一个switch语句,以返回一周中的字符串:
std::String printable_DOW(int DOW)
{
switch (DOW)
case 0:
return "Sunday";
case 1:
return "Monday";
case 2:
return "Tuesday";
case 3:
return "Wednesday";
case 4:
return "Thursday";
case 5:
return "Friday";
case 6:
return "Saturday";
}
和print_date
功能:
void print_date(Date d)
{
std::cout<< printable_DOW(d.DayOfWeek)
<< ", " << d.Day << "." << d.Month << "." d.Year;
}
并且很容易将它们放在一起并使用它们:
int main
{
Date my_date;
my_date.Day = 1;
my_date.Month = 1;
my_date.Year = 2000;
my_date.DayOfWeek = 0; //assuming 0 == Sunday, 1 = Monday...
for (int daycount = 0; daycount < 5114 /*days since 1/1/2000 to today*/; daycount++)
{
increment_date(my_date);
//debug:
print_date(my_date);
}
//print "today's" date:
print_date(my_date);
}
作为一个班级: 它主要在这里和(大多数)工作。随意编辑人物!
class date
{
private:
unsigned short int day;
unsigned short int month;
unsigned short int year;
unsigned short int day_of_week;
int month_limit();
bool is_leap_year();
public:
date();
date(int in_day, int in_month, int in_year, int in_day_of_week);
date& date::operator=(date rhs)
date& operator++(); //pre-increment (++date)
date operator++(int); //post-increment (date++)
//these are "special" they don't work exactly as you might think and are slightly broken right now,
//but I'm putting them in regardless
//they also don't work on DOW right now.
date& operator+=(const date& rhs)
date& operator-=(const date& rhs)
inline date operator+(date lhs, const date& rhs)
inline date operator-(date lhs, const date& rhs)
}
//phwew
date::date(int in_day, int in_month, int in_year, int in_day_of_week)
{
this->day = in_day;
this->month = in_month;
this->year = in_year;
this->day_of_week = in_doay_of_week;
}
date::month_limit()
{
switch (this->month)
{
case 4:
case 6:
case 9:
case 11:
{
return 30;
break;
}
case 1:
case 3:
case 5:
case 7:
case 8:
case 12:
{
return 31;
break;
}
case 2:
if (is_leap_year(this->year))
{
return 29;
break;
}
else
{
return 28;
break;
}
}
}
bool is_leap_year()
{
if (this->year % 4 != 0) return false;
else
if (this->year % 100 != 0) return true;
else
if (this->year % 400 != 0) return false;
else
return true;
}
date& date::operator=(date rhs)
{
swap(rhs);
return *this;
}
date& date::operator++()
{
this->day_of_week = (this->day_of_week + 1) % 7; //increase weekday
this->day++;
if (++(this->day) > month_limit()) //increase day, if larger than month size...
{
this->day = 1; //reset day to 1
if (++this->month > 12) //increase month, if larger than year size
{
this->month = 1; //reset month to 1
this->year++; //increase year
}
}
return *this;
}
date date::operator++(int)
{
date tmp(*this);
operator++();
return tmp;
}
//adds years on, then months, then days
date& date::operator+=(const date& rhs)
{
this->year += rhs.year;
this->month += rhs.month;
this->day += rhs.day;
if (this->month > 12) //get to the right month
{
this->year = this->month / 12;
this->month = this->month % 12;
}
if (this->day > month_limit())
{
this->month = this->day / month_limit();
this->day = this->day % month_limit();
if (this->month > 12) //recalculate **yes, I know this is currently wrong if more than one month is added on in days**
{
this->year = this->month / 12;
this->month = this->month % 12;
}
}
return *this;
}
inline date date::operator+(date lhs, const date& rhs)
{
lhs += rhs;
return lhs;
}
//subtracts years, then months, then days
date& date::operator-=(const date& rhs)
{
if ((rhs.year < this->year) || ((rhs.year == this->year) && (rhs.month < this->month))
|| (((rhs.year == this->year) && (rhs.month == this->month)) && (rhs.day < this->day)
{
swap(rhs);
}
this->year -= rhs.year;
this->month -= rhs.month;
this->day -= rhs.day;
return *this;
}
inline date date::operator+(date lhs, const date& rhs)
{
lhs += rhs;
return lhs;
}