본문 바로가기

프로그래밍/자바(JAVA)

[자바] 달력프로그램 알고리즘에 대해..

달력프로그램 알고리즘에 대해..

실제 달력을 출력하기는 매우 쉽습니다.

간단한 프로그램이긴 하지만, 코드로 짜려면 꽤 길것으로 생각되기때문에

방법만 설명 드리지요...


달력을 만들때는 기준일을 언제로 잡을 것인가가 관건입니다. 이건 차후에 생각하기로 하구요.
먼저 직관적으로 달력을 분석합니다.
달력으로 프린트 될수 있는 경우는 모두 몇가지 경우가 있을까요?

그달이 큰달인 경우 31일까지 있을 것이고, 작은달인경우 30일 혹은 28일, 29일까지 있을 것이니까
모두 4가지 경우가 있겠군요..
그리고, 각 달의 첫째 날이 일요일부터 토요일까지 일수 있으니까 7가지의 경우가 나옵니다.
그렇다면 앞의 4가지 경우에 7가지 경우를 곱해서 28가지 경우를 만들어 놓는다면 모든 달력을 표현할 수 있습니다.(예를들어 30일까지 있으면서 1일이 월요일인달, 화요일인달 등등)

이 28가지 경우를 모두 배열 등으로 만들어놓아도 상관없고,
2개의 인자를 주어서
분기문과 반복문을 사용해서 출력폼을 맞추어 출력하는 함수를 만드는 방법도 있습니다
예) print_cal(31, 0); //31일까지 있으면서 1일이 일요일인 달을 출력하라)

이건 편하신대로 하시구요...

이제 사용자로부터 어떤 연도와 달을 입력받았을때, 그달이 며칠까지 있는지와 1일이 무슨 요일인지만 알아낸다면 달력 프로그램은 끝나는 것입니다...^^;

그달이 며칠까지 있는지를 알아내는 것은 간단하지요?
31 , 28 or 29 ,31, 30, 31, 30, 31, 31, 30, 31, 30, 31 (1~12월까지) 입니다.

여기서 2월달이 걸리는군요.. 바로 윤년 때문입니다.. 

윤년을 계산해 내는 방법은 간단합니다..

1. 기본적으로 4의 배수가 되는 해는 윤년입니다...
2. 다만 100의 배수가 되는 해는 윤년이 아닙니다...
3. 그중에서 또 400의 배수가 되는 해는 윤년입니다..


위 3가지 규칙을 만족하는 해는 윤년이 되니까 입력받은 연도를 놓고 지지고 볶아보면 윤년인지 아닌지 알수 있겠지요...^^;

그렇다면 마지막으로 그 달의 1일이 무슨요일인지만 알아내는 일만 남았군요...^^;
이것을 위해서 아까 말씀드린 기준일 이라는 것이 필요합니다..
계산으로 알아내야 하는데,, 4년마다 한번씩 끼어있는 윤년이 골치 아프게 합니다..^^;

우리는 라이브러리 함수를 사용하지 않고, 이것을 알아내기로 합시다!!
우선 기준일을 잡습니다.. 0년 1월 1일을 기준일고, 그날이 무슨요일인지를 알아냅시다.
어떻게 알아내냐구요? 계산으로 충분히 알아낼 수 있습니다.. 화이팅!!
1년은 365일로, 7로 나누면 1이 남습니다..
즉 1년이 가면 같은 날의 요일이 하루씩 밀려난다는 이야기가 됩니다.

만약 윤년이라면 요일이 2개 밀려나겠지요?

예를들어 만약 2004년 1월 1일이 월요일이었다면 2005년 1월 1일은 화요일이어야 하는데,,
2004년이 윤년이기때문에 2일 밀려나서 수요일이 된다는 얘깁니다. 이제 감이 잡히나요?

2004년 1월 1일을 월요일로 잡고 날짜를 계산해봅시다..
2004년 1월 1일부터 1년씩 줄어들수록 날짜가 하루씩 앞으로 당겨진다면
`0년` 에는 총 며칠이 앞으로 당겨질까요?
2004 - 0 = 2004 일이 앞으로 당겨지겠지요...

여기서 끝나지 않습니다.. 윤년이 있기때문입니다..
2004년과 0년의 사이에 있는 윤년을 계산해 내야 합니다.
앞으로 가는 것이기때문에 2004년은 포함되지 않고, 0년은 윤년에 포함해야 겠지요..
2000 / 4 = 500 번의 윤년이 있었고, 그중에서 2000 / 100 = 20 번은 윤년이 아니니까
480번의 윤년이 있었고, 또 그중에서 2000 / 400 = 5 번은 윤년이니까 총 484번의 윤년이 있었군요...

이것을 2004에 더하면 2004 + 484 = 2488일을 앞으로 당겨야 하니까 이것을 7로 나눠볼까요?
2488/7 = 355 , 나머지 3 이군요... 결론적으로 3일을 앞으로 당겨야 합니다.
실제 2004년 1월 1일이 목요일이니까, 3일 앞으로 당기면 월요일이 되는군요...