Java

[Java자바] 입력한 년/월/일의 요일 구하기. 배열 | 접근제어지시자 | 클래스 설계

dev_haha 2023. 2. 25. 16:50

2월16일
Test099.java

※ 문제 조건
사용자로부터 년, 월, 일을 입력받아
해당 날짜의 요일을 출력하는 프로그램을 구현한다.
단, 달력 클래스(Calender)는 사용하지 않는다.
또한, 클래스의 개념을 활용하여 작성할 수 있도록 한다.
(→ WeekDay 클래스 설계)
그리고, 배열의 개념도 적용시켜 작성할 수 있도록 한다.
접근제어지시자의 개념도 확인하여 작성할 수 있도록 한다.
최종적으로
WeekDay 클래스 설계를 통해
Test099 클래스의 main() 메소드가 정상적으로 프로그램 실행될 수 있도록 한다.
실행 예)
년 월 일 입력(공백 구분) : 2023 2 16 
>> 2023년 2월 16일 → 목요일
계속하려면 아무 키나 누르시오...

년 월 일 입력(공백 구분) : 1997 7 14
> 1997년 7월 14일 → ???요일
계속...

※ Hint
- 1년 1월 1일 → "월요일"
- 1년은 365일이 아니다.
- 2월의 마지막 날짜가 29일 → 윤년
  2월의 마지막 날짜가 28일 → 평년
- 윤년의 판별 조건 → 년도가 4의 배수이면서 100의 배수가 아니거나, 400의 배수이면 윤년이다. 그 이외의 년도는 평년.

 

*해결책(수혀니의 도움)
대략은 -> 모든 년,월,일을 날수의 합으로 만들어서 7로 나눈 나머지에 따른 요일 출력.
날수의 누적합 변수 sum 만들고
1) 입력받은 연도 y에서 y-1년도 까지의 날수를 sum에 누적합
1-1) 윤년판단하여 윤년이면 366일 더하고
1-2) 평년이면 365일을 더한다.

2) 입력받은 월 m에서 m-1월까지의 날수를 sum에 누적합
2-1) 윤년이면 2월달은 29일로 해서 누적합
2-2) 평년이면 2월달은 28일로 해서 누적합

3) 입력받은 날 d를 sum에 누적합
4) sum을 7로 나눠서 나머지에 따른 요일을 출력하도록 배열 만든당(ex) 나머지0 → 일, 나머지1 → 월)

우선은 내가 푼 코드, 밑에는 강사님의 풀이 코드.



// 내 풀이 코드

import java.util.Scanner;

class WeekDay
{
	int y, m, d;		//사용자가 입력하는 년월일을 담아내는 변수
    boolean b;			// 윤년 판단 변수
    int sum = 0;		// 날수의 누적합 변수
    
    char[] dayarr = {'일', '월', '화', '수', '목', '금', '토'};
    
    void getDate()		// 년, 월, 일을 받는 메소드
    {
    	Scanner sc = new Scanner(System.in);
        
        System.out.print(" 년 월 일 입력(공백 구분) : ");
        y = sc.nextInt();
        m = sc.nextInt();
        d = sc.nextInt();
    }
    
    void getSum()		// 년, 월, 일을 날수의 합으로 만드는 메소드
    {
    	for (int i=0; i<y; i++)		// 1 ~ (y-1)년간의 날수를 누적합
        {
        	if ((y%4==0 && y%100!=0) || (y%400==0))		//윤년일 경우
            {
            	b = true;	//윤년 판단 변수 true
                sum += 366;		//날수 누적합에 366을 더해주고
            }
            else				// 평년일 경우
            {
            	b = false;		//윤년 판단 변수 false
                sum += 365;		//날수 누적합에 365를 더해주고
            }
        }
        
        for (int i=0; i<m; i++)		// 1 ~ (m-1)월간의 날수를 누적합
        {
        	if(i==1||i==3|i==5|i==7|i==8|i==10|i==12)	//한달이 31일인 달에는
            	sum += 31;		// 날수 누적합에 31을 더해주고
            else if(i==4|i==6|i==9|i==11)		//한달이 30일인 달에는
            	sum += 30;		//날수 누적합에 30을 더해주고
            else			//2월달을 결정
            {
            	if(b==true)		//윤년이면
                	sum += 29;
                else			//평년이면
                	sum += 28;
            }
        }
        
        sum += d;				// 1 ~ d까지의 일수를 누적합
    }
    
    char getDay()				// 누적합을 7로 나눈 나머지를 통해 요일 정하는 메소드
    {
    	char day = dayarr[sum%7];	// 누적합을 나눈 7의 나머지를 배열의 인덱스로 사용
        return day;				// 요일을 반환
    }
    
    void print(char day)		//요일을 변수로 받아서 결과를 출력하는 메소드
    {
        System.out.printf(">> %d년 %m월 %d일 → %c요일\n", y, m, d, day);
    }
}


public class Test099
{
	public static void main(String[] args)
    {
    	//WeekDay 클래스 기반의 인스턴스 생성
        WeekDay ob = new WeekDay();
        
        ob.getData();
        ob.getSum();
        char day = ob.getDay();
        ob.print(day);
    }
}

// 강사님 풀이 코드

import java.util.Scanner;

class WeekDay
{
	// 주요 변수 선언 → 속성
    private int y, m, d;		//-- 사용자가 입력한 연, 월, 일을 담아낼 변수
    				// 이 클래스 내에서만 사용할 변수이니까 private
    // 메소드 정의 → 기능: 연, 월, 일 입력받기
    public void input()		// 클래스의 외부에서 산출될 수 있도록 public
    {
    	Scanner sc = new Scanner(System.in);
        
        System.out.print("년 월 일 입력(공백 구분) : ");		//2023 2 16
        y = sc.nextInt();
        m = sc.nextInt();
        d = sc.nextIn();
    }
    
    //메소드 정의 → 기능: 요일 산출하기
    public Stirng week()		//결과 요일을 출력할거니까 String이 반환 타입
    {
    	// 각 월의 마지막 날짜(각 월의 최대값)를 배열 형태로 구성
        int[] months = {31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        // 2월달 자리에는 임의의로 0. 아직 결정한게 아님
        
        // 각각 요일의 이름을 배열의 형태로 구성
        String[] weekNames = {"일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"};
        
        // check~!!!
        int nalsu;		// 날 수 종합할 변수
        
        // 윤년에 따른 2월의 날 수 계싼
        // 입력 년도가 윤년이라면... 2월의 마지막 날짜를 29일로 설정
        // 입력 년도가 평년이라면... 2월의 마지막 날짜를 28일로 설정
        // ---------                  ---------------
        //    y                         months[1]
        if ((y%4==0 && y%100!=0) || (y%400==0)		//-- 입력 년도가 윤년이라면...
        	months[1] = 29;
        else			//-- 입력 년도가 평년이라면...
        	months[1] = 28;
            
        // ① 1년 1월 1일부터 입력받은 년도의 이전 년도 12월 31일까지의 날 수 계산
        //   이전년도*365 + 4년마다 하루씩 더해주고 - 100년마다 하루씩 빼주고 + 400년마다 하루씩 더해주고
        nalsu = (y-1)*365 + (y-1)/4 - (y-1)/100 + (y-1)/400;
        
        // 테스트
        //System.out.println("날 수 : " + nalsu);
        //--==>> 년 월 일 입력(공백 구분) : 2023 2 16
        //		날 수 : 738520
        //		1년 1월 1일 ~ 2022년 12월 31일 까지의 총 날 수 .
        
        // ② 입력받은 월의 이전 월 까지의 날 수 계산 후
        //	 이 결과를 1번 결과에 더하는 연산
        for (int i=0; i<(m-1); i++)
        	nalsu += months[i];			//-- nalsu를 months 배열의 i번째 값 만큼 증가
            
        //테스트
        //System.out.println("날 수 : " + nalsu);
        //--==>> 년 월 일 입력(공백 구분) : 2023 2 16
        //		날 수 : 738551
        //		1년 1월 1일 ~ 2023년 1월 31일 까지의 총 날 수.
        
        // ③ 입력받은 일의 날짜만큼 날 수 계산 후
        //		이 계산결과를 2번 결과에 더하는 연산
        nalsu += d;		//-- nalsu를 d만큼 증가
        
        // 테스트
        //System.out.println("날 수 : " + nalsu);
        //--==>> 년 월 일 입력(공백 구분) : 2023 2 16
        //		날 수 : 738567
        //		1년 1월 1일 ~ 2023년 2월 16일 까지의 총 날 수
        
        //여기까지 수행하면 날 수 연산 끝. 
        
        //무슨 요일인지 확인하는 연산
        int w = nalsu % 7;	
        //-- 전체날수 % 7 == 0 → 일요일
        //-- 전체날수 % 7 == 1 → 월요일
        //-- 전체날수 % 7 == 2 → 화요일
        
        //테스트
        //SYstem.out.println("w : " + w);
        //--==>> 년 월 일 입력(공백 구분) : 2023 2 16
        //		w : 4
        //			→ 전체날수 % 7 == 4 → 목요일
        
        return weekNames[w];		//목요일 반환
        
    } // week()메소드 close
    
    public void print(String day)
    {
    	System.out.printf(">> %d년 %d월 %d일 → %s\n", y, m, d, day);
    }
}


public class Test099_1
{
	public static void main(String[] args)
    {
    	//WeekDay 클래스 기반 인스턴스 생성
        WeekDay wd = new WeekDay();
        
        //입력 메소드 호출
        wd.input();
        
        //요일 산출 메소드 호출
        String result = wd.week();
        
        //출력 메소드 호출
        wd.print(result);
    }
}