欧拉计划 #19,只有从 1900 年开始,答案才正确?
Project Euler #19, Answer is only correct when starting from year 1900?
我一直在试图理解为什么以下代码仅在开始年份设置为 1900 时给出正确答案。问题指定星期日应从 1901 年 1 月 1 日开始计算。
我以为我在意识到没有年份 0 时就明白了,所以 1900 实际上是 1901...但是当将 while 循环从 2000 年调整到 1999 年时,这不起作用。
我完全惊讶为什么这会使用错误的起始年份给出正确答案。
public class Euler19
{
public static void main(String[] args)
{
int day = 2; //Jan 1st, 1901 is a Tuesday, This should be 3 but only works if set to 2 for Monday
int sundays = 0;
int month = 1;
int monthDays = 1;
int year = 1901;
while(year <= 2000)
{
switch(month) //Case for each month
{
case 1: //January
if(monthDays == 31)
{
month++;
monthDays = 1;
}
break;
case 2: //February
if((year % 4 == 0) && (year != 1900)) //Leap days
{
if(monthDays == 29)
{
month++;
monthDays = 1;
}
}
else
{
if(monthDays == 28)
{
month++;
monthDays = 1;
}
}
break;
case 3: //March
if(monthDays == 31)
{
month++;
monthDays = 1;
}
break;
case 4: //April
if(monthDays == 30)
{
month++;
monthDays = 1;
}
break;
case 5: //May
if(monthDays == 31)
{
month++;
monthDays = 1;
}
break;
case 6: //June
if(monthDays == 30)
{
month++;
monthDays = 1;
}
break;
case 7: //July
if(monthDays == 31)
{
month++;
monthDays = 1;
}
break;
case 8: //August
if(monthDays == 31)
{
month++;
monthDays = 1;
}
break;
case 9: //September
if(monthDays == 30)
{
month++;
monthDays = 1;
}
break;
case 10: //October
if(monthDays == 31)
{
month++;
monthDays = 1;
}
break;
case 11: //November
if(monthDays == 30)
{
month++;
monthDays = 1;
}
break;
case 12: //December
if(monthDays == 31)
{
month = 1;
monthDays = 1;
year++;
}
break;
}
if(day == 1 && monthDays == 1) //Sunday is 1st day of the week
{
sundays++;
}
if(day == 7)
{
day = 0;
}
day++;
monthDays++;
}
System.out.println("Total Sundays: " + sundays);
}
}
所以你的问题是你的范围,现在它是从 1900 到 2000 不包括在内,它应该是 1901 到 2000 包括在内。简而言之,答案是您需要将 while 循环更改为 while(year<=2000)
您的错误在别处:您的程序正在跳过每个月的第一天。您使用错误的起始年份恰好得到了正确的结果纯属巧合。
从 1900 年 1 月 1 日星期一开始(无论那天是否真的是星期一),您都正确地计算到 1 月,并认为 1 月 31 日是星期三。到目前为止,它在先决条件下是正确的。然后麻烦来了:由于 month
是 1 而 monthDays
是 31,所以您将 month 递增到 2 并在 switch
语句中将 monthDays
设置为 1。在你的 switch
和你的两个 if
语句之后,你将 day
(正确)和 increment monthDays
增加到 2 , 它给出了一个不正确的值。你现在得到了 1900 年 2 月 2 日星期四,这与 1 月 31 日是星期三不一致。
每次新月开始时都会发生相同的错误增量。
我建议你学习使用调试器。这将使您能够自己找到此类错误。
我一直在试图理解为什么以下代码仅在开始年份设置为 1900 时给出正确答案。问题指定星期日应从 1901 年 1 月 1 日开始计算。
我以为我在意识到没有年份 0 时就明白了,所以 1900 实际上是 1901...但是当将 while 循环从 2000 年调整到 1999 年时,这不起作用。
我完全惊讶为什么这会使用错误的起始年份给出正确答案。
public class Euler19
{
public static void main(String[] args)
{
int day = 2; //Jan 1st, 1901 is a Tuesday, This should be 3 but only works if set to 2 for Monday
int sundays = 0;
int month = 1;
int monthDays = 1;
int year = 1901;
while(year <= 2000)
{
switch(month) //Case for each month
{
case 1: //January
if(monthDays == 31)
{
month++;
monthDays = 1;
}
break;
case 2: //February
if((year % 4 == 0) && (year != 1900)) //Leap days
{
if(monthDays == 29)
{
month++;
monthDays = 1;
}
}
else
{
if(monthDays == 28)
{
month++;
monthDays = 1;
}
}
break;
case 3: //March
if(monthDays == 31)
{
month++;
monthDays = 1;
}
break;
case 4: //April
if(monthDays == 30)
{
month++;
monthDays = 1;
}
break;
case 5: //May
if(monthDays == 31)
{
month++;
monthDays = 1;
}
break;
case 6: //June
if(monthDays == 30)
{
month++;
monthDays = 1;
}
break;
case 7: //July
if(monthDays == 31)
{
month++;
monthDays = 1;
}
break;
case 8: //August
if(monthDays == 31)
{
month++;
monthDays = 1;
}
break;
case 9: //September
if(monthDays == 30)
{
month++;
monthDays = 1;
}
break;
case 10: //October
if(monthDays == 31)
{
month++;
monthDays = 1;
}
break;
case 11: //November
if(monthDays == 30)
{
month++;
monthDays = 1;
}
break;
case 12: //December
if(monthDays == 31)
{
month = 1;
monthDays = 1;
year++;
}
break;
}
if(day == 1 && monthDays == 1) //Sunday is 1st day of the week
{
sundays++;
}
if(day == 7)
{
day = 0;
}
day++;
monthDays++;
}
System.out.println("Total Sundays: " + sundays);
}
}
所以你的问题是你的范围,现在它是从 1900 到 2000 不包括在内,它应该是 1901 到 2000 包括在内。简而言之,答案是您需要将 while 循环更改为 while(year<=2000)
您的错误在别处:您的程序正在跳过每个月的第一天。您使用错误的起始年份恰好得到了正确的结果纯属巧合。
从 1900 年 1 月 1 日星期一开始(无论那天是否真的是星期一),您都正确地计算到 1 月,并认为 1 月 31 日是星期三。到目前为止,它在先决条件下是正确的。然后麻烦来了:由于 month
是 1 而 monthDays
是 31,所以您将 month 递增到 2 并在 switch
语句中将 monthDays
设置为 1。在你的 switch
和你的两个 if
语句之后,你将 day
(正确)和 increment monthDays
增加到 2 , 它给出了一个不正确的值。你现在得到了 1900 年 2 月 2 日星期四,这与 1 月 31 日是星期三不一致。
每次新月开始时都会发生相同的错误增量。
我建议你学习使用调试器。这将使您能够自己找到此类错误。