是否有公式计算任何一天的日期?我被Project Euler#19困住了

时间:2013-05-04 16:51:55

标签: java algorithm math

我在做Euler项目#19。这是州:

您将获得以下信息,但您可能更愿意为自己做一些研究。

1900年1月1日是星期一。 九月三十天, 四月,六月和十一月。 其余的都有三十一个, 仅拯救二月, 其中有二十八,风雨无阻。 在闰年,二十九岁。 闰年发生在任何一年,可被4整除,但除非可被400整除,否则不会在一个世纪上。 在二十世纪的第一个月(1901年1月1日至2000年12月31日),有多少个星期日下降?

我在互联网上搜索了一些计算星期几的公式。我发现Zeller formula非常出色。 W = [C / 4] - 2C + y + [y / 4] + [13 *(M + 1)/ 5] + d - 1.(C是世纪+ 1,y是一年中的最后两个数字) 但是,当我检查1900.01.01时它会变成错误,它应该是星期一,但根据公式,即6(即星期六)

我查了很多日期,几乎所有的日期都适合这个公式。但是仍有更少的日子不匹配。 我的Java代码如下所示:

package number;

public class CountingSundays {
    public static int calculateWeek(int year, int month, int date){
        int c = year/100;
        int y = year%100;
        int w = c/4-2*c+y+y/4+13*(month+1)/5+date-1;
        w = (w%7 + 7)%7;
        return w;
    }
    public static void main(String[] args) {
//      int w = calculateWeek(1900, 01, 01);
//      System.out.println(w);
        int count = 0;
        for(int i = 1901; i <= 2000; i++)
            for(int j = 1; j <= 12; j++)
                if(calculateWeek(i, j, 01) == 0)
                    count++;
        System.out.println(count);
    }
}

对于不匹配,我的输出为173,这不是必需的结果171。 有人可以给我一些提示吗?或者我的代码有什么问题吗?

3 个答案:

答案 0 :(得分:2)

如果您的意思是阳历和英语,那么

GregorianCalendar gc = new GregorianCalendar(1, Calendar.JANUARY, 1900);
System.out.println(gc.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG, Locale.ENGLISH));

输出

Monday

答案 1 :(得分:2)

wikipedia article you cited

m is the month (3 = March, 4 = April, 5 = May, ..., 14 = February)

For January 1, 2000, the date would be treated as the 13th month of 1999,
so the values would be:
    q = 1
    m = 13
    K = 99
    J = 19

所以如果你想使用这个公式,你可能应该相应调整你的输入值,即添加这样的东西

if (month <= 2) {
    month += 12;
    year--;
}

答案 2 :(得分:1)

您可以在指定的年份范围内循环每个月,并在日历对象上设置日期,然后阅读每个月的第一天的星期几。

import java.util.Calendar;
import java.util.GregorianCalendar;

public class CountingSundays {

    public static void main(String[] args) {
        GregorianCalendar gc = new GregorianCalendar(1, Calendar.JANUARY, 1900);

        int count = 0;
        for (int i = 1901; i < 2001; i++) {
            gc.set(GregorianCalendar.YEAR, i);
            for (int j = 0; j < 12; j++) {
                gc.set(GregorianCalendar.MONTH, j);
                if (gc.get(GregorianCalendar.DAY_OF_WEEK) == GregorianCalendar.SUNDAY) {
                    count++;
                }
            }
        }
        System.out.println(count);
    }
}

请注意,年份和月份在循环中发生变化,但日期(日期)保持设置为1。