Do it! 자료구조와 함께 배우는 알고리즘 입문[자바편] 연습문제와 실습문제입니다.


2023.01.01을 기준으로 100일 전은2022년 9월 23일(기준날 미포함)이고,

100일 후는2023년 4월 11일이다.

이러한 알고리즘을 자바로 구현하면 아래와 같다.

클래스 선언부

static class YMD { 
		int year;
		int month;
		int day;

		YMD(int y, int m, int d) //생성자
		{
			this.year = y;
			this.month = m;
			this.day = d;
		}
		
		int[][] arr = {
		        {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, //평년 arr[0][]
		        {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} //윤년 arr[1][]
		};
	
		static int isLeap(int year) { //윤년이면 1을 리턴, 평년이면 0을 리턴
			return (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) ? 1 : 0;
		}
		
		YMD after(int n) //n일 후 날짜를 리턴하는 메소드
		{
			YMD temp = new YMD(this.year, this.month, this.day);
			if (n < 0)
				return (before(-n));

			temp.day += n;

			while (temp.day > arr[isLeap(temp.year)][temp.month - 1]) {
				temp.day -= arr[isLeap(temp.year)][temp.month - 1];
				if (++temp.month > 12) {
					temp.year++;
					temp.month = 1;
				}
			}
			return temp;
		}
		
		YMD before(int n) //n일 전 날짜를 리턴하는 메소드
		{
			YMD temp = new YMD(this.year, this.month, this.day);
			if (n < 0)
				return (after(-n));

			temp.day -= n;

			while (temp.day < 1) {
				if (--temp.month < 1) {
					temp.year--;
					temp.month = 12;
				}
				temp.day += arr[isLeap(temp.year)][temp.month - 1];
			}
			return temp;
		}
	}

 

실행예제

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    System.out.print("날짜를 입력하세요. 입력 예 : 2023 1 18\n");
    int y, m, d;
    y = sc.nextInt();
    m = sc.nextInt();
    d = sc.nextInt();
    YMD date = new YMD(y, m, d);

    System.out.print("몇 일 앞/뒤의 날짜를 구할까요?:");
    int n = sc.nextInt();

    YMD d1 = date.after(n);
    System.out.printf("%d일 뒤의 날짜는 %d년 %d월 %d일입니다.\n", n, d1.year, d1.month, d1.day);

    YMD d2 = date.before(n);
    System.out.printf("%d일 앞의 날짜는 %d년 %d월 %d일입니다.\n", n, d2.year, d2.month, d2.day);
}
/*
날짜를 입력하세요. 입력 예 : 2023 1 18
2023 1 18
몇 일 앞/뒤의 날짜를 구할까요?:1000
1000일 뒤의 날짜는 2025년 10월 14일입니다.
1000일 앞의 날짜는 2020년 4월 23일입니다.
*/

네이버 날짜 계산기는 기준일을 1일로 치지만 위 알고리즘은 기준일을 0일로 삼는다.

네이버는 내일을 2일째 되는날이라고 하지만, 위 알고리즘은 1일째 되는날이라고 한다.

설명
arr의 행에 오는 isLeap()메소드는 temp의 연도가 윤년이면 1, 평년이면 0을 리턴한다.
열에오는 temp의 month에 -1을 한 이유는 배열의 인덱스는 0부터 시작하기 때문이다.
2023.01.18에 1000일을 한 temp객체는 초기에 2023.01.1018로 되어있다.
while루프는 temp의 day가 달의 일수보다 같거나 작을 때 까지 반복한다.
day는 루프를 돌면서 계속 달의 일수만큼 감소된다.
달의 일수가 감소할 때, 달은 계속 증가하게 되고, 달이 12를 넘어가면 연도를 +1해준다.

2024년은 윤년이므로 2월이 29일 인 것을 볼 수 있다.