BOJ_5635 / 생일

차_현·2025년 2월 6일
0

📌 문제 탐색하기

  • 입력:
    • 첫 줄에 학생 수 n (1 ≤ n ≤ 100)
    • 이후 n개의 줄에 "이름 dd mm yyyy" 형식의 생일 정보 제공
    • 이름은 최대 15자, yyyy (1990 ≤ yyyy ≤ 2010), mm (1 ≤ mm ≤ 12), dd (1 ≤ dd ≤ 31)
    • 생일이 같은 사람은 없음
  • 출력:
    • 가장 나이가 적은 사람(최근에 태어난 사람)의 이름을 출력
    • 가장 나이가 많은 사람(가장 오래된 생일)의 이름을 출력

📌 어떤 알고리즘?

  • 정렬(Comparator)
    • LocalDate를 이용하여 날짜 정보를 Comparable하게 다룰 수 있음
    • Comparator.comparing()을 사용하여 생일을 기준으로 정렬 가능
    • 정렬 후 첫 번째 요소(가장 오래된 생일)와 마지막 요소(가장 최근 생일)를 출력

📌 코드 설계하기

  1. 입력 처리:
    • BufferedReader로 입력을 받음
    • StringTokenizer로 이름과 날짜를 분리하여 저장
    • LocalDate 클래스를 활용해 날짜 정보를 변환
    • BirthInfo 클래스를 만들어 이름과 날짜를 함께 저장
  2. 정렬:
    • Comparator.comparing(BirthInfo::getBirthDate)를 사용하여 생일을 기준으로 오름차순 정렬
  3. 출력:
    • 정렬된 리스트의 첫 번째 요소: 가장 나이가 많은 사람
    • 정렬된 리스트의 마지막 요소: 가장 나이가 적은 사람

📌 정답 코드

package BOJ_5635;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.time.LocalDate;
import java.util.*;

public class BOJ_5635 {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static int n;
    static List<BirthInfo> birthList = new ArrayList<>();

    public static void main(String[] args) throws IOException {
        n = Integer.parseInt(br.readLine());

        for (int i = 0; i < n; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine(), " ");
            String name = st.nextToken();
            int day = Integer.parseInt(st.nextToken());
            int month = Integer.parseInt(st.nextToken());
            int year = Integer.parseInt(st.nextToken());
            birthList.add(new BirthInfo(name, LocalDate.of(year, month, day)));
        }

        // 나이가 많은 사람이 먼저 오도록 정렬 (즉, 연도가 더 작은 사람이 앞에 오도록)
        birthList.sort(Comparator.comparing(BirthInfo::getBirthDate));

        // 가장 나이가 어린 사람 (최근에 태어난 사람)
        System.out.println(birthList.get(n - 1).getName());
        // 가장 나이가 많은 사람 (가장 오래된 생일)
        System.out.println(birthList.get(0).getName());
    }

    // 이름과 생일을 함께 저장할 클래스
    public static class BirthInfo {
        private final String name;
        private final LocalDate birthDate;

        public BirthInfo(String name, LocalDate birthDate) {
            this.name = name;
            this.birthDate = birthDate;
        }

        public LocalDate getBirthDate() {
            return birthDate;
        }

        public String getName() {
            return name;
        }
    }
}

📌 Comparator를 활용한 정렬 방법

1️⃣ Comparator.comparing()을 사용한 정렬

birthList.sort(Comparator.comparing(BirthInfo::getBirthDate));
  • BirthInfo::getBirthDate는 각 객체의 getBirthDate() 값을 기준으로 정렬하는 메서드 참조
  • Comparator.comparing()을 사용하면 비교 기준이 되는 필드를 바로 지정 가능
  • 기본적으로 오름차순 정렬(연도가 작을수록 앞에 배치)

2️⃣ 내림차순 정렬하려면?

birthList.sort(Comparator.comparing(BirthInfo::getBirthDate).reversed());
  • .reversed()를 붙이면 가장 최근에 태어난 사람이 앞에 배치됨

📌 시간 복잡도?

  • 시간 복잡도:
    • O(n log n) (정렬 연산이 가장 큰 연산)
  • 공간 복잡도:
    • O(n) (리스트에 n개의 객체 저장)

📌 Comparator 정렬을 활용한 이유

  1. LocalDate 자체가 Comparable을 구현하고 있어, compareTo()를 통해 날짜 비교 가능
  2. 객체 리스트를 손쉽게 정렬할 수 있음 (별도로 compare() 메서드를 구현할 필요 없음)
  3. 간결한 코드: Comparator.comparing()을 사용하면 가독성이 높아짐

💡 정리하자면

  • Comparator.comparing(BirthInfo::getBirthDate)을 사용하면 BirthInfo 객체를 birthDate 기준으로 정렬
  • LocalDate의 compareTo()를 활용하여 연, 월, 일을 자동 비교
  • 정렬 후 birthList.get(n - 1)가 가장 나이가 적은 사람, birthList.get(0)가 가장 나이가 많은 사람이 됨

0개의 댓글