2009-06-20 4 views
28

Я следую книге «Искусство и наука Явы», и она показывает, как вычислить високосный год. В книге используется библиотека ACM Java Task Force.Java-код для вычисления високосного года

Вот код книги использует:

import acm.program.*; 

public class LeapYear extends ConsoleProgram { 
    public void run() 
    { 

     println("This program calculates leap year."); 
     int year = readInt("Enter the year: ");  

     boolean isLeapYear = ((year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0)); 

     if (isLeapYear) 
     { 
      println(year + " is a leap year."); 
     } else 
      println(year + " is not a leap year."); 
    } 

} 

Теперь, это то, как я подсчитал, високосный год.

import acm.program.*; 

public class LeapYear extends ConsoleProgram { 
    public void run() 
    { 

     println("This program calculates leap year."); 
     int year = readInt("Enter the year: "); 

     if ((year % 4 == 0) && year % 100 != 0) 
     { 
      println(year + " is a leap year."); 
     } 
     else if ((year % 4 == 0) && (year % 100 == 0) && (year % 400 == 0)) 
     { 
      println(year + " is a leap year."); 
     } 
     else 
     { 
      println(year + " is not a leap year."); 
     } 
    } 
} 

Есть ли что-то не так с моим кодом, или я должен использовать тот, который предоставляется книгой?

EDIT :: Оба вышеуказанного кода работают нормально, что я хочу спросить, какой код является лучшим способом для вычисления високосного года.

+1

Лучший код будет использовать доверенную библиотеку вместо этого. Предположение Клетуса об использовании класса Calendar является ярким примером этого. –

+0

Вы правы, если я использую обычную библиотеку Java. Но, в моем курсе, я использовал библиотеку ACM Java Task Force. http://www-cs-faculty.stanford.edu/~eroberts/jtf/ –

+1

Вот такая же тема. http://stackoverflow.com/questions/7395699/calculate-leap-year-in-java/7395759#7395759 – CharithJ

ответ

13

Они выглядят одинаково для меня, хотя отмечают, что эта строка в коде имеет некоторую избыточность:

else if ((year % 4 == 0) && (year % 100 == 0) && (year % 400 == 0)) 

может быть заменен:

else if (year % 400 == 0) 

Если число кратно 400 то это автоматически также кратен 100 и 4.

редактировать: (! 7 лет спустя)

Обратите внимание, что вышеуказанное предполагает наличие предшествующего if ((year % 4 == 0) && year % 100 != 0) оригинального вопроса!

В любом случае, используя код библиотеки является лучшим решением, ответ Клетуса должен быть принятым одно: https://stackoverflow.com/a/1021373/8331

+1

Коррекция, 4, а не 4! :) – Sev

+0

Hah исправлено, чтобы избежать путаницы между (!) Восклицанием и не оператором;) –

+1

@OP, как только вы сделаете эту модификацию, код «книг», как вы выразились, и ваш код станет функционально идентичным. – Sev

20

Я предлагаю вам поместить этот код в метод и создать модульный тест.

public static boolean isLeapYear(int year) { 
    assert year >= 1583; // not valid before this date. 
    return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0); 
} 

В модульном тесте

assertTrue(isLeapYear(2000)); 
assertTrue(isLeapYear(1904)); 
assertFalse(isLeapYear(1900)); 
assertFalse(isLeapYear(1901)); 
+0

Спасибо, им только новичок в программировании на Java. До сих пор я не изучал модульное тестирование. Но спасибо за ответ :) –

+0

Если бы я был преподавателем, сначала я бы преподавал модульное тестирование. В классах математики и инженерной математики обычной практикой является возвращение результатов обратно через формулы для их проверки; модульное тестирование позволяет компьютеру делать то же самое для вашей программы. –

+0

Im follow Standfords Методология программирования Курс видео, лектор использует книгу «Искусство и наука о Java», чтобы преподавать методологию программирования, а не преподавать Java. Im на главе 4 и до сих пор не существует темы тестирования модулей. –

3

Это почти всегда неправильно иметь повторение в программном обеспечении. В любой инженерной дисциплине форма должна следовать функции, и у вас есть три ветви для чего-то, что имеет два возможных пути - это либо високосный год, либо нет.

Механизм, который имеет тест в одной строке, не имеет этой проблемы, но, как правило, было бы лучше разделить тест на функцию, которая принимает int, представляющую год, и возвращает логическое значение, представляющее, является ли год это високосный год. Таким образом, вы можете что-то сделать с этим другим, который печатает на стандартный вывод на консоли и может более легко протестировать его.

В коде, который, как известно, превышает его бюджет исполнения, обычно организуют тесты, чтобы они не были избыточными и выполняли тесты в порядке, который возвращается раньше. Пример wikipedia делает это - в течение многих лет вы должны вычислять по модулю 400 100 и 4, но для нескольких вам нужно только по модулю 400 или 400 и 100. Это небольшая оптимизация с точки зрения производительности (в лучшем случае только одна из сотни входы), но это также означает, что код имеет меньшее количество повторений, и программисту набрать меньше.

+0

Спасибо, ваш ответ имеет смысл. –

66

Правильная реализация:

public static boolean isLeapYear(int year) { 
    Calendar cal = Calendar.getInstance(); 
    cal.set(Calendar.YEAR, year); 
    return cal.getActualMaximum(Calendar.DAY_OF_YEAR) > 365; 
} 

Но если вы собираетесь заново это колесо затем:

public static boolean isLeapYear(int year) { 
    if (year % 4 != 0) { 
    return false; 
    } else if (year % 400 == 0) { 
    return true; 
    } else if (year % 100 == 0) { 
    return false; 
    } else { 
    return true; 
    } 
} 
+3

+1 для использования кода библиотеки. Я бы предложил добавить примечание, потому что 400 - это мультиплекс 100, который вы тестируете для 400 до 100, а не для исходного кода. –

+0

@cletus, где значение DAY_OF_YEAR передано в cal.getActualMaximum(); –

+0

эта строка должна быть 'cal.getActualMaximum (cal.DAY_OF_YEAR);' –

6

Псевдо код из Википедии переведен в самый компактный Java

(year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0)) 
+0

хорошее покрытие в простом коде –

+0

Просто для того, чтобы сказать это: всегда указывайте ссылку на любой источник, который использовался для компиляции ответа (даже если его легко найти как содержимое Википедии). –

6

Самый эффективный тест на скачок:

if ((year & 3) == 0 && ((year % 25) != 0 || (year & 15) == 0)) 
{ 
    /* leap year */ 
} 

Это отрывок из моего подробного ответа на https://stackoverflow.com/a/11595914/733805

+0

Вышеупомянутое также является хорошим решением для поиска високосного года –

-1
boolean leapYear = ((year % 4) == 0); 
+3

Это неправильно. 1900 год не високосный год. – Artemix

+1

Только одно условие, упомянутое выше, недостаточно для определения високосного года. Вышеизложенное неверно. Поэтому вам нужно применить дополнительные условия, на которые отвечает The Sphinc: (год% 400 == 0) || ((год% 4 == 0) && (год% 100! = 0)) –

-1
import javax.swing.*; 
public class LeapYear { 
    public static void main(String[] args) { 
    int year; 
String yearStr = JOptionPane.showInputDialog(null, "Enter radius: "); 

year = Integer.parseInt(yearStr); 

boolean isLeapYear; 
isLeapYear = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); 

if(isLeapYear){ 
JOptionPane.showMessageDialog(null, "Leap Year!"); 
} 
else{ 
JOptionPane.showMessageDialog(null, "Not a Leap Year!"); 
    } 
    } 
    } 
0

Это то, что я придумал. Существует дополнительная функция, чтобы проверить, не превышает ли int дату, на которую были наложены исключения (год $ 100, год% 400). До 1582 года этих исключений не было.

import java.util.Scanner; 

public class lecture{ 


public static void main(String[] args) { 
    boolean loop=true; 
    Scanner console = new Scanner(System.in); 
    while (loop){ 
     System.out.print("Enter the year: "); 

     int year= console.nextInt(); 
     System.out.println("The year is a leap year: "+ leapYear(year)); 
     System.out.print("again?: "); 
     int again = console.nextInt(); 
     if (again == 1){ 
      loop=false; 
     }//if 
    } 
} 
public static boolean leapYear (int year){ 
    boolean leaped = false; 
    if (year%4==0){ 
     leaped = true; 
     if(year>1582){ 
      if (year%100==0&&year%400!=0){ 
       leaped=false; 
      } 
     } 
    }//1st if 
    return leaped; 
} 
} 
0
public static void main(String[] args) 
{ 

String strDate="Feb 2013"; 
     String[] strArray=strDate.split("\\s+");   

     Calendar cal = Calendar.getInstance(); 
     cal.setTime(new SimpleDateFormat("MMM").parse(strArray[0].toString())); 
     int monthInt = cal.get(Calendar.MONTH); 
     monthInt++; 
     cal.set(Calendar.YEAR, Integer.parseInt(strArray[1]));   
     strDate=strArray[1].toString()+"-"+monthInt+"-"+cal.getActualMaximum(Calendar.DAY_OF_MONTH); 

     System.out.println(strDate);  



} 
0
import java.util.Scanner; 

    public class LeapYear { 
    public static void main(String[] args) { 
     // TODO Auto-generated method stub 
     Scanner input = new Scanner(System.in); 
     System.out.print("Enter the year then press Enter : "); 
     int year = input.nextInt(); 

     if ((year < 1580) && (year % 4 == 0)) { 
      System.out.println("Leap year: " + year); 
     } else { 
      if ((year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0)) { 
       System.out.println("Leap year: " + year); 
      } else { 
       System.out.println(year + " not a leap year!"); 
      } 

     } 
    } 
} 
0

Как wikipedia государства алгоритм високосного года должен быть

(((year%4 == 0) && (year%100 !=0)) || (year%400==0)) 

Вот пример программы how to check for leap year.

0

Ваш код, как есть, без дополнительного класса, похоже, не работает для универсальной java. Вот упрощенная версия, которая работает в любом месте, опираясь больше на ваш код.

import java.util.*; 
public class LeapYear { 
    public static void main(String[] args) { 
     int year; 
     { 
      Scanner scan = new Scanner(System.in); 
      System.out.println("Enter year: "); 
      year = scan.nextInt(); 

      if ((year % 4 == 0) && year % 100 != 0) { 
       System.out.println(year + " is a leap year."); 
      } else if ((year % 4 == 0) && (year % 100 == 0) 
        && (year % 400 == 0)) { 
       System.out.println(year + " is a leap year."); 
      } else { 
       System.out.println(year + " is not a leap year."); 
      } 
     } 
    } 
} 

Ваш код, в контексте, работает так же хорошо, но обратите внимание, что код книги всегда работает, и тщательно протестирован. Не сказать, что твой нет. :)

9

java.time.Year::isLeap

Я хотел бы, чтобы добавить новый java.time способ сделать это с Year класса и isLeap методом:

java.time.Year.of(year).isLeap() 
+0

В текущем году високосный год? (используя java 8) 'Year.now(). isLeap()' –

+0

@ SheamusO'Halloran Лучше указать желаемый/ожидаемый часовой пояс, а не полагаться неявно на текущий часовой пояс JVM, который может быть изменен в любой момент любым кода в любом приложении внутри этой JVM: 'Year.now (ZoneId (« Америка/Монреаль »)) .isLeap()' –

5

От GregorianCalendar исходного кода Java-:

/** 
* Returns true if {@code year} is a leap year. 
*/ 
public boolean isLeapYear(int year) { 
    if (year > changeYear) { 
     return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); 
    } 

    return year % 4 == 0; 
} 

Где changeYear - это год, когда юлианский календарь становится Григорианским календарем (1582).

Юлианский календарь определяет високосные годы каждые четыре года, в то время как Григорианский календарь опускает годы столетия, которые не делятся на 400.

В Gregorian Calendar documentation вы можете найти более подробную информацию о нем.

1

Вы можете задать GregorianCalendar класс для этого:

boolean isLeapyear = new GregorianCalendar().isLeapYear(year); 
2

Если вы используете java8:

java.time.Year.of(year).isLeap() 

реализация Java из выше метода:

public static boolean isLeap(long year) { 
     return ((year & 3) == 0) && ((year % 100) != 0 || (year % 400) == 0); 
    } 
0

простым способом та сделать java високосный год и более понятно понимать enter code here

import java.util.Scanner; 

класса que19 {

public static void main(String[] args) { 

    Scanner input=new Scanner(System.in); 

    double a; 

    System.out.println("enter the year here "); 
    a=input.nextDouble(); 
    if ((a % 4 ==0) && (a%100!=0) || (a%400==0)) { 
     System.out.println("leep year"); 

    } 
    else { 
     System.out.println("not a leap year"); 
    } 
} 

}

Смежные вопросы