코테초보 코커두드

[코딩 초보의 탐구] 백준 10814번 : 나이순 정렬(자바)과 Comparator

코커두드 2023. 11. 13. 22:08

2015년에 발매된 Knxwledge의 Hud dreems

 

🎧 오늘은 클라우드 서비스 정리를 했습니다. 하면서 들을 음악을 선택했는데 손가락이 닿는대로 눌렀더니 저 앨범이었어요. 그런데 너무나도 탁월한 선택이었던 거 있죠?

 

그럼 바로 문제를 풀러 갑시다.

 

1. 문제 파악

출처 : 백준

 

✅ 제목을 보자마자 정렬 문제임을 알 수 있습니다. 문제를 읽어보면 list에 담아서 정렬을 하면 되겠구나가 바로 떠올랐어요. 나이순으로 정렬하는 것은 Arrays.sort 메서드를 사용하면 될 것 같았고 실버5 치고는 간단해보였습니다.

✅ 하지만 리스트로 만드는 과정에서 에러를 많이 만나게 됩니다. 찾아보다가 Comparable과 Comparator에 대해 알게되었고, 이를 알아보기 시작했습니다.

 

✅ Comparable과 Comparator 모두 객체의 정렬을 위한 인터페이스라는 공통점을 가지고 있습니다. 

 

 

2. Comparable

◾ Comparable은 양수, 음수 혹은 0을 리턴값으로 반환하여 정렬을 합니다. CompareTo라는 메서드를 오버라이딩 해서 객체간 비교를 합니다.

◾ 아래는 Comparable의 예시 코드입니다. 입력한 두 개의 과일 이름의 알파벳순 순서를 if문을 돌면서 파악할 수 있습니다.

public class ComparableExample implements Comparable<ComparableExample> {

    private String name;

    public ComparableExample(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public int compareTo(ComparableExample other) {
        return this.name.compareTo(other.getName());
    }

    public static void main(String[] args) {
        ComparableExample example1 = new ComparableExample("Tomato");
        ComparableExample example2 = new ComparableExample("Banana");

        int result = example1.compareTo(example2);

        if (result < 0) {
            System.out.println(example1.getName() + " comes before " + example2.getName());
        } else if (result > 0) {
            System.out.println(example1.getName() + " comes after " + example2.getName());
        } else {
            System.out.println(example1.getName() + " is equal to " + example2.getName());
        }
    }
}

 

◾ 위 코드를 돌리면 아래와 같은 결과가 도출됩니다. 

Tomato comes after Banana

 

◾ 만약 Tomato를 Apple로 바꾸면 다음과 같은 결과가 도출됩니다.

Apple comes before Banana

 

 

 

3. Comparator

◾ Comparator 인터페이스는 두 객체를 비교하는 정렬 규칙을 정의하여 정렬할 수 있습니다.

◾ compare 메서드를 오버라이딩 해서 사용합니다.

 

◾ 아래는 Comparator를 사용하여 과일 이름을 이름의 길이에 따라 오름차순으로 정렬하는 코드입니다.

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class ComparatorExample {
    public static void main(String[] args) {

        List<String> fruits = new ArrayList<>();

        fruits.add("Apple");
        fruits.add("Mango");
        fruits.add("Tomato");
        fruits.add("Banana");
        fruits.add("Pineapple");
        fruits.add("Orange");

        Comparator<String> lengthComparator = Comparator.comparingInt(String::length);
        Collections.sort(fruits, lengthComparator);

        System.out.print("Sorted by length : ");
        for (String fruit : fruits) {
            System.out.print(fruit + " ");
        }
    }
}

 

 

◾ 길이 말고 알파벳순으로 정렬하는 코드는 다음과 같습니다.

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class ComparatorExample {
    public static void main(String[] args) {

        List<String> fruits = new ArrayList<>();

        fruits.add("Apple");
        fruits.add("Mango");
        fruits.add("Tomato");
        fruits.add("Banana");
        fruits.add("Pineapple");
        fruits.add("Orange");

        Comparator<String> alphabeticalComparator = Comparator.naturalOrder();
        Collections.sort(fruits, alphabeticalComparator);

        System.out.print("Sorted by alphabet : ");
        for (String fruit : fruits) {
            System.out.print(fruit + " ");
        }
    }
}

 

 

 

정답 제출 코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Comparator;
import java.util.StringTokenizer;

// 나이순 정렬 (실버5)
public class p10814 {

    int age;
    String name;

    public p10814(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        int N = Integer.parseInt(br.readLine());

        p10814[] list= new p10814[N];

        for (int i = 0; i < N; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            list[i] =  new p10814(Integer.parseInt(st.nextToken()), st.nextToken());
        }

        Arrays.sort(list, new Comparator<p10814>() {

            @Override
            public int compare(p10814 o1, p10814 o2) {
                return o1.age - o2.age;
            }

        });


        for (int i = 0; i < N; i++) {
            System.out.println(list[i].age + " " + list[i].name);
        }

        br.close();

    }
}

◾ 제출할 때에는 p10814 부분을 모두 Main으로 바꾸어서 제출하였습니다.

◾ 위에 보여드린 예시코드에서는 compare를 메서드로 오버라이드 해오지 않았었는데, 이 코드에서는 compare를 오버라이드 하였습니다. Integer.compare 메서드를 사용할 수도 있으나, o1.age - o2.age를 리턴해서 메서드를 구현하는 방법을 사용하였습니다. 

 

◾ 위가 Integer.compare 메서드 사용, 아래가 o1.age - o2.age 사용한 코드입니다. 메모리는 전자가 조금 더 적고, 시간은 더 걸리네요. 어떤 방식을 사용하여도 괜찮을 것 같습니다.

 

 
 

 

🚨 본 포스팅은 개인적인 학습 목적으로 작성되었습니다.

정확하고 날카로운 풀이를 원하시는 분들은 고수분들의 포스팅을 보시기를 권장드립니다.