윤년 계산을 위한 Java 코드
-
06-07-2019 - |
문제
나는 "The Art and Science of Java" 책을 읽고 있으며 윤년을 계산하는 방법을 보여줍니다.이 책은 ACM Java Task Force의 라이브러리를 사용합니다.
책에서 사용하는 코드는 다음과 같습니다.
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.");
}
}
}
내 코드에 문제가 있나요? 아니면 책에서 제공하는 코드를 사용해야 하나요?
편집하다 ::위의 코드는 모두 잘 작동합니다. 제가 묻고 싶은 것은 윤년을 계산하는 가장 좋은 방법은 어떤 코드인지입니다.
해결책
제 눈에는 똑같아 보이지만 코드에 다음 줄이 약간 중복되어 있다는 점에 유의하세요.
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)
원래 질문에서!
cletus의 답변이 허용되어야 합니다. https://stackoverflow.com/a/1021373/8331
(내 답변을 삭제하고 싶지만 허용되는 답변이므로 삭제할 수 없습니다)
다른 팁
올바른 구현은 다음과 같습니다.
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;
}
}
이 코드를 메소드에 넣고 단위 테스트를 작성하는 것이 좋습니다.
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));
new GregorianCalendar().isLeapYear(year);
Wikipedia의 의사 코드는 가장 컴팩트 한 자바로 번역되었습니다.
(year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0))
가장 효율적인 도약 테스트 :
if ((year & 3) == 0 && ((year % 25) != 0 || (year & 15) == 0))
{
/* leap year */
}
이것은 나의 자세한 답변에서 발췌 한 것입니다 https://stackoverflow.com/a/11595914/733805
Java의 GregorianCalendar Sourcecode에서 :
/**
* 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가 연도 인 Julian 달력은 Gregorian 달력 (1582)이됩니다.
줄리안 달력은 4 년마다 도약 년을 지정하는 반면, 그레고 리아 캘린더는 세기를 생략하여 400 명으로 나눌 수 없다.
에서 그레고리 캘린더 문서 그것에 대한 자세한 정보를 찾을 수 있습니다.
소프트웨어에서 반복되는 것은 거의 항상 잘못입니다. 모든 공학 분야에서 형태는 기능을 따라야하며, 두 개의 가능한 경로가있는 세 가지 지점이 있습니다.
한 줄에 테스트를하는 메커니즘에는 해당 문제가 없지만 일반적으로 테스트를 1 년을 나타내는 int를 나타내는 함수로 테스트를 분리하고 연도가 윤년인지 여부를 나타내는 부울을 반환하는 것이 좋습니다. . 이렇게하면 콘솔에서 표준 출력으로 인쇄하는 다른 작업을 수행 할 수 있으며 더 쉽게 테스트 할 수 있습니다.
성과 예산을 초과하는 것으로 알려진 코드에서는 테스트를 정리하여 중복되지 않고 조기에 반환하는 순서대로 테스트를 수행하는 것이 일반적입니다. Wikipedia 예제는이 작업을 수행합니다. 대부분의 해 동안 모듈로 400,100 및 4를 계산해야하지만, 몇몇 경우에는 모듈로 400 또는 400 및 100 만 필요합니다. 이것은 성능 측면에서 작은 최적화입니다 (기껏해야 100 명 중 하나만 입력이 영향을 받았지만 코드가 반복이 적고 프로그래머가 입력하는 것이 적다는 것을 의미합니다.
Java8을 사용하는 경우 :
java.time.Year.of(year).isLeap()
위의 방법의 Java 구현 :
public static boolean isLeap(long year) {
return ((year & 3) == 0) && ((year % 100) != 0 || (year % 400) == 0);
}
당신은 물어볼 수 있습니다 그레고리 언 달력 이것에 대한 수업 :
boolean isLeapyear = new GregorianCalendar().isLeapYear(year);
이것이 제가 생각해 낸 것입니다. 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;
}
}
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);
}
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!");
}
}
}
}
처럼 위키 백과 도약 연도의 상태 알고리즘은이어야합니다
(((year%4 == 0) && (year%100 !=0)) || (year%400==0))
다음은 샘플 프로그램입니다 도약 연도를 확인하는 방법.
추가 클래스가없는 코드는 Universal 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.");
}
}
}
}
코드는 맥락에서도 작동하지만 그 책 코드에 주목하십시오. 항상 작동합니다, 철저히 테스트됩니다. 당신의 말은 아닙니다. :)
가장 쉬운 방법은 자바를 도약하고 이해하기 위해 더 명확하게 만듭니다.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");
}
}
}
과정과 함께 : https://tmc.mooc.fi , 운동 중 하나가 이런 종류의 문제 였고, 나는이 답을 썼습니다.
import java.util.Scanner;
public class LeapYear {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
System.out.println("Type a year: ");
int year = Integer.parseInt(reader.nextLine());
if (year % 400 == 0 && year % 100 == 0 && year % 4 == 0) {
System.out.println("The year is a leap year");
} else
if (year % 4 == 0 && year%100!=0 ) {
System.out.println("The year is a leap year");
} else
{
System.out.println("The year is not a leap year");
}
}
}
이 답변 훌륭하지만 그리스도 앞에서 몇 년 동안 작동하지 않을 것입니다 (분량 그레고리 캘린더 사용). BC 년 동안 일하기를 원한다면 다음 적응을 사용하십시오.
public static boolean isLeapYear(final int year) {
final Calendar cal = Calendar.getInstance();
if (year<0) {
cal.set(Calendar.ERA, GregorianCalendar.BC);
cal.set(Calendar.YEAR, -year);
} else
cal.set(Calendar.YEAR, year);
return cal.getActualMaximum(Calendar.DAY_OF_YEAR) > 365;
}
그해 -5 (예 : 기원전 4)를 고려하여 직접 직접 확인할 수 있습니다. -1 년 (AD 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!");
}
}
}
boolean leapYear = ( ( year % 4 ) == 0 );