Java 爪哇岛,数一数从1901年到2000年每个月1日的星期日数

Java 爪哇岛,数一数从1901年到2000年每个月1日的星期日数,java,arrays,loops,Java,Arrays,Loops,我对编程和Java都是新手,我正试图通过ProjectEuler网站自学。我正在尝试完成以下问题:,即: 在二十世纪有多少个星期天是在一个月的第一天 世纪(1901年1月1日至2000年12月31日) 我想解决这个问题的方法是,制作一个代表日历的2D数组,通过数到7来循环数组,然后每次我数到7时,在数组中的该点上加1。最后,我将对数组的第一行求和,这应该是一个月的第一个星期天的数量 但是我的循环有问题,我的计数到一个月结束时会重置为7,我不知道如何阻止它这样做 这是我的密码: public cl

我对编程和Java都是新手,我正试图通过ProjectEuler网站自学。我正在尝试完成以下问题:,即:

在二十世纪有多少个星期天是在一个月的第一天 世纪(1901年1月1日至2000年12月31日)

我想解决这个问题的方法是,制作一个代表日历的2D数组,通过数到7来循环数组,然后每次我数到7时,在数组中的该点上加1。最后,我将对数组的第一行求和,这应该是一个月的第一个星期天的数量

但是我的循环有问题,我的计数到一个月结束时会重置为7,我不知道如何阻止它这样做

这是我的密码:

public class Problem019 {
    public static void main (String[] args){

        //System.out.println(LeapYearTest(1996));
        int ThirtyOne = 31;
        int Thirty = 30;
        int FebNorm = 28;
        int FebLeap = 29;
        int a, b, c, Day, e = 0, f = 0;
        int Calander[] []= new int [12] [] ;

        Calander[0] = new int [ThirtyOne];
        Calander[1] = new int [FebNorm];
        Calander[2] = new int [ThirtyOne];
        Calander[3] = new int [Thirty];
        Calander[4] = new int [ThirtyOne];
        Calander[5] = new int [Thirty];
        Calander[6] = new int [ThirtyOne];
        Calander[7] = new int [ThirtyOne];
        Calander[8] = new int [Thirty];
        Calander[9] = new int [ThirtyOne];
        Calander[10] = new int [Thirty];
        Calander[11] = new int [ThirtyOne];

        for (a=1901;a<2001;a++){
            //System.out.println(a);
            if (LeapYearTest(a))
            {
                Calander[1] = new int [FebLeap];
            }
            else
            {
                Calander[1] = new int [FebNorm];
            }

            for (e=0;e<Calander.length;e++)
            {   
                System.out.println("e: " + e);
                f=0;

                while (f<Calander[e].length)
                {   

                    //System.out.println(Calander[e].length);
                    Day=1;
                    while (Day<8 && f<Calander[e].length)
                    {   
                        System.out.println("f: " + f + "\tDay: " + Day + "\tCalander[e][f]: " + Calander[e][f]);
                        Day++;
                        f++;

                        if (f<Calander[e].length && f!=0 && Day==7)
                        {
                        Calander[e][f]+= 1;
                        }

                    }

                }
            }
            //System.out.println(a);
        }
        for (b=0;b<Calander.length;b++)
        {   
            System.out.print(Calander[0][b]);
        }
    }   


    public static boolean LeapYearTest(int x)
    {
        if (x%4==0 || x%400==0){
            return true;
        }
        if (x%100==0){
            return false;
        }
        else return false;
    }

}
我如何设置循环,使那天不会在月底重置?或者有没有另一种方法可以解决这个问题,而不涉及这么多嵌套循环


谢谢

如果有一个从1901年到2001年递增的外循环和一个检查一月->十二月的内循环,然后看看那个月的第一个月是不是星期天,会不会快得多

总共100*12次迭代,最多10行代码

编辑:在此基础上展开

你可以从两个方面来解决这个问题——看看所有的星期天,看看它们是不是在一个月的第一天,或者看看所有月份的第一天,看看是不是星期天

未测试代码:

Calendar calendar = Calendar.getInstance();
int count = 0;
for(int i=1901;i<2000;i++){
    for(int j=1;i<12;j++){
        calendar.set(Calendar.YEAR, i);
        calendar.set(Calendar.MONTH,j);
        calendar.set(Calendar.DAY,1);
        if(calendar.get(Calendar.DAY_OF_WEEK).equals(Calendar.SUNDAY)){
            count++;
        }
    }
}
Calendar Calendar=Calendar.getInstance();
整数计数=0;

对于(inti=1901;i这是我的建议。它使用公历来确定日期,如果是星期天

import java.util.Date;
import java.util.GregorianCalendar;

public class SundayOfXX {

    public static void main(String [] argv) {
        int counter = 0;
        for (int year = 1901, last_year = 2000; year <= last_year ; year++) {
            for (int month = 1, last_month = 12; month <= last_month ; month++) {
                Date d = new GregorianCalendar(year,month-1,1).getTime(); // GregorianCalendar use 0 for January
                if (d.getDay() == 0) { // sunday is day number 0
                    counter++;
                    System.out.println(String.valueOf(counter) + " " + d);
                }
            }
        }
        System.out.println("Total sunday in XX century: "+counter);
    }
}
import java.util.Date;
导入java.util.GregorianCalendar;
公共类SundayOfXX{
公共静态void main(字符串[]argv){
int计数器=0;

对于(int year=1901,last_year=2000;year我认为您需要扔掉现有代码,重新开始。由于您正试图通过解决Project Euler问题来学习如何编写代码,我不会给您提供代码来破坏您的乐趣。似乎您确实需要完整的工作代码,因此我已修复了您的代码,包括一些到期时出现的错误问题陈述中一些你可能误解或忽略的微妙细节

只是为了好玩,让我们看看你要修复的代码的即时问题……/P> 当您最初声明日期时,将其初始化为1。然后替换此行:

Day=1;
为此:

if (Day > 7) {
    Day = 1;
}
并将其移动到一个月内的循环中

但是仍然存在一个严重的问题。你每年都会覆盖你的Feb数组。你应该只初始化它一次,并将其长度设置为29。但这也有一个不幸的副作用,那就是打破任何依赖于
日历[月]。长度的循环,所以你也必须考虑到这一点

您真正需要跟踪的是每月第一个星期日的数量,因此只需存储并增加一个变量。这通过覆盖Feb数组解决了上述问题,因为您不会使用它(或任何其他月份的数组)还有。另一方面,如果你真的只想练习使用数组,你可以使用三维数组(其中额外的维度是年份)但是我敢猜测,大多数Java程序员在大多数情况下都使用列表而不是数组,而且当他们使用数组时,他们几乎不会使用具有多个维度的数组

还有几个注释

import java.util.Calendar;

public class P19 {

    public static void main(String[] args) {
        int result = 0;
        for ( int year = 1901 ; year <= 2000 ; year++ ) {
            for ( int month = Calendar.JANUARY ; month <= Calendar.DECEMBER ; month++ ) {
                Calendar c = getCalendar(year, month, 1);
                if ( c.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY ) {
                    result++;
                }
            }
        }
        System.out.println(result);
    }

    private static Calendar getCalendar(int year, int month, int day) {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.YEAR, year);
        c.set(Calendar.MONTH, month);
        c.set(Calendar.DAY_OF_MONTH, day);      // or Calendar.DATE
        return c;
    }

}
您的外部
while
循环是冗余的

您的
LeapYearTest
方法将错误地为所有可被100整除的闰年返回true(所有可被100整除的年份也可被4整除,因此您永远不会进入测试可被100整除的年份的if块)

最后,您将在一月的每一天循环(而不是在每个月的第一天循环)

还请注意,问题指出

1900年1月1日是星期一

但是你应该找到从1901年1月1日开始的周日

在修复了这些错误和其他错误(例如循环中的条件)之后,我在下面提供了一个完整的代码版本。请注意,通过更多地使用模数(%)操作符,并且不计算一个月中其他几天的星期日数,您可以轻松地优化此代码,使其在一小部分时间内运行(因为你最终还是把它们扔掉了)

公共类问题019{
公共静态void main(字符串[]args){
最终整数为31;
最终整数=30;
最终整数FebNorm=28;
最终int FebLeap=29;
int numOfSundays=0;
整数日历[][]=新整数[12][];
日历[0]=新整数[31];
日历[1]=新整数[FebLeap];
日历[2]=新整数[31];
日历[3]=新整数[30];
日历[4]=新整数[31];
日历[5]=新整数[30];
日历[6]=新整数[31];
日历[7]=新整数[31];
日历[8]=新整数[30];
日历[9]=新整数[31];
日历[10]=新整数[30];
日历[11]=新整数[31];
int dayOfWeek=1;
对于(整数年=1900;年份<2001;年份++){
对于(int month=0;monthpublic class Problem019 {
    public static void main (String[] args){

        final int ThirtyOne = 31;
        final int Thirty = 30;
        final int FebNorm = 28;
        final int FebLeap = 29;
        int numOfSundays = 0;

        int calendar[][]= new int [12][];

        calendar[0] = new int [ThirtyOne];
        calendar[1] = new int [FebLeap];
        calendar[2] = new int [ThirtyOne];
        calendar[3] = new int [Thirty];
        calendar[4] = new int [ThirtyOne];
        calendar[5] = new int [Thirty];
        calendar[6] = new int [ThirtyOne];
        calendar[7] = new int [ThirtyOne];
        calendar[8] = new int [Thirty];
        calendar[9] = new int [ThirtyOne];
        calendar[10] = new int [Thirty];
        calendar[11] = new int [ThirtyOne];

        int dayOfWeek = 1;
        for (int year = 1900; year < 2001; year++) {
            for (int month = 0; month < calendar.length; month++) {   
                int dayOfMonth=0;

                int daysInMonth;
                if (month == 1) {
                    daysInMonth = isLeapYear(year) ? FebLeap : FebNorm;
                }
                else {
                    daysInMonth = calendar[month].length;
                }

                while (dayOfWeek < 8 && dayOfMonth < daysInMonth) {   
                    System.out.println("year: " + year + "\tday: " + dayOfWeek
                            + "\tcalendar["+month+"]["+dayOfMonth+"]: " + calendar[month][dayOfMonth]);

                    if (dayOfWeek == 7 && year > 1900) {
                        calendar[month][dayOfMonth]++;

                        if (dayOfMonth == 0) {
                            numOfSundays++;
                        }
                    }

                    dayOfMonth++;

                    dayOfWeek++;
                    if (dayOfWeek > 7) {
                        dayOfWeek=1;
                    }
                }
            }
        }

        for (int month = 0; month < calendar.length; month++) {   
            System.out.println(calendar[month][0]);
        }

        System.out.println(numOfSundays);
    }   

    public static boolean isLeapYear(int year){
        if (year % 400 == 0) {
            return true;
        }
        else if (year % 100 == 0) {
            return false;
        }
        else if (year % 4 == 0){
            return true;
        }
        else {
            return false;
        }
    }
}
import java.util.Calendar;
public class Problem019 {   

    public static void main (String[] args){

        Calendar calendar = Calendar.getInstance();
        int countFirstSunday = 0;
        for(int year = 1901; year <= 2000 ; year++) {
            for(int month = 0; month <= 11; month++) {
                calendar.set(year, month, 1);
                if(calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
                    countFirstSunday++;
                }
            }
        }
        System.out.println("Sundays as the first of month: " + countFirstSunday);
    }

}
public static void main(String[] args) {
  final int thirtyOne = 31, thirty = 30;
  final int calendar[][] = new int[12][];
  final int[] febLeap = new int[29];
  final int[] febNorm = new int[28];
  calendar[0] = new int[thirtyOne];
  calendar[2] = new int[thirtyOne];
  calendar[3] = new int[thirty];
  calendar[4] = new int[thirtyOne];
  calendar[5] = new int[thirty];
  calendar[6] = new int[thirtyOne];
  calendar[7] = new int[thirtyOne];
  calendar[8] = new int[thirty];
  calendar[9] = new int[thirtyOne];
  calendar[10] = new int[thirty];
  calendar[11] = new int[thirtyOne];
  int dow = 0; // set to day of week for Jan 1 1901
  for (int y = 1901; y < 2001; y++) {
    calendar[1] = leapYearTest(y)? febLeap : febNorm;
    for (int m = 0; m < calendar.length; m++)
      for (int d = 0; d < calendar[m].length; d++)
        if (dow++ % 7 == 0) calendar[m][d]++;
  }
  int sumSundays = calendar[0][0] + febLeap[0] + febNorm[0];
  for (int i = 2; i < calendar.length; i++) sumSundays += calendar[i][0];
  System.out.println("Number of Sundays is " + sumSundays);
}

public static boolean leapYearTest(int x) {
  if (x % 4 == 0 || x % 400 == 0)
    return true;
  return x % 100 != 0;
}
public static void main(String[] args) {
  final int[] mLens = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  int dow = 0; // initialize to day of week on Jan 1, 1901
  int suns = 0;
  for (int y = 1901; y < 2001; y++)
    for (int m = 0; m < mLens.length; m++) {
      if (dow++ % 7 == 0) suns++;
      final int mLen = mLens[m] + leapAdd(y, m);
      for (int d = 1; d < mLen; d++) dow++;
    }
  System.out.println(suns);
}

static int leapAdd(int y, int m) {
  if (m != 1) return 0;
  if (y % 4 == 0 || y % 400 == 0) return 1;
  return y % 100 == 0 ? 0 : 1;
}
    for (int m = 0; m < mLens.length; m++) {
      if (dow == 0) suns++;
      final int mLen = mLens[m] + leapAdd(y, m);
      dow = (dow + mLen) % 7;
    }
class MyDate { ... } // support adding a number of days and comparing with another MyDate
MyDate end = new MyDate(31. Dec 2000)
MyDate start = new MyDate(first sunday in 20th century)
int count = start.mday == 1 ? 1 : 0;
start.add(7);
while (start < end) (
    if (start.mday == 1) count++;
    start.add(7);
}
import java.util.Calendar;

public class P19 {

    public static void main(String[] args) {
        int result = 0;
        for ( int year = 1901 ; year <= 2000 ; year++ ) {
            for ( int month = Calendar.JANUARY ; month <= Calendar.DECEMBER ; month++ ) {
                Calendar c = getCalendar(year, month, 1);
                if ( c.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY ) {
                    result++;
                }
            }
        }
        System.out.println(result);
    }

    private static Calendar getCalendar(int year, int month, int day) {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.YEAR, year);
        c.set(Calendar.MONTH, month);
        c.set(Calendar.DAY_OF_MONTH, day);      // or Calendar.DATE
        return c;
    }

}
public class P19 {

    public static void main(String[] args) {
        // 1 Jan 1900 - Monday
        // 1900 is not leap => it has 365 days
        // 365 % 7 = 1 => 1 Jan 1901 - Tuesday => 6 Jan 1901 - Sunday

        int yearStart = 1901, yearEnd = 2000;
        int monthStart = 1, monthEnd = 12;
        int dayStart = 6, dayEnd = 31;
        Date dateStart = new Date(yearStart, monthStart, dayStart);
        Date dateStop = new Date(yearEnd, monthEnd, dayEnd);

        int result = 0;
        while (Date.compareDates(dateStart, dateStop) < 0) {
            if (dateStart.day == 1) {
                result++;
            }
            dateStart.addDays(7);
        }
        System.out.println(result);
    }

}

class Date {
    int year;
    int month;
    int day;

    Date(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }

    public void addDays(int days) {
        int numberOfDaysForMonth = getTotalMonthDays(month, year);
        day += days;
        if (day >= numberOfDaysForMonth) {
            day -= numberOfDaysForMonth;
            month++;
            if (month > 12) {
                month = 1;
                year++;
            }
        }

    }

    public static int compareDates(Date d1, Date d2) {
        if (d1.year == d2.year && d1.month == d2.month && d1.day == d2.day) {
            return 0;
        }
        if (d1.year < d2.year) {
            return -1;
        }
        if (d1.year == d2.year && d1.month < d2.month) {
            return -1;
        }
        if (d1.year == d2.year && d1.month == d2.month && d1.day < d2.day) {
            return -1;
        }
        return 1;
    }

    private int getTotalMonthDays(int m, int y) {
        if (m == 2 && isLeapYear(y)) {
            return 29;
        }
        if (m == 2) {
            return 28;
        }
        if (m == 4 || m == 6 || m == 9 || m == 11) {
            return 30;
        }
        return 31;
    }

    private boolean isLeapYear(int y) {
        if (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) {
            return true;
        }
        return false;
    }

}
public class CountingSundays {

    public static void main(String[] args) {

        int lastDayOfPreviousMonth = 6; //31 Dec 1899 is Sunday as 1 Jan 1900 is Monday

        int countOfSundayOnFirstOfMonth = 0;

        for (int year = 1900; year <= 2000; year++) {
            for (int month = 1; month <= 12; month++) {
                int dayOnFirstOfThisMonth = (lastDayOfPreviousMonth + 1) % 7;
                if (year > 1900 && dayOnFirstOfThisMonth == 6)
                    countOfSundayOnFirstOfMonth++;
                switch (month) {
                case 1: // Jan
                case 3: // Mar
                case 5: // May
                case 7: // Jul
                case 8: // Aug
                case 10: // Oct
                case 12: // Dec
                    lastDayOfPreviousMonth = (lastDayOfPreviousMonth + 3) % 7;
                    break;
                case 4: // Apr
                case 6: // Jun
                case 9: // Sep
                case 11: // Nov
                    lastDayOfPreviousMonth = (lastDayOfPreviousMonth + 2) % 7;
                    break;
                case 2: // Feb
                    if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
                        lastDayOfPreviousMonth = (lastDayOfPreviousMonth + 1) % 7;
                }
            }
        }


        System.out.println(countOfSundayOnFirstOfMonth);
    }

}