코딩테스트/programming_JAVA

[Java] baekjoon_11650 : 좌표 정렬하기

prometedor 2024. 1. 15. 14:24

정렬

좌표 정렬하기 : Silver5

https://www.acmicpc.net/problem/11650

 

11650번: 좌표 정렬하기

첫째 줄에 점의 개수 N (1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 N개의 줄에는 i번점의 위치 xi와 yi가 주어진다. (-100,000 ≤ xi, yi ≤ 100,000) 좌표는 항상 정수이고, 위치가 같은 두 점은 없다.

www.acmicpc.net

 

풀이

import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        int N = Integer.parseInt(br.readLine());
        String[][] arr = new String[N][2];
        
        for (int i = 0; i < N; i++) {
          StringTokenizer st = new StringTokenizer(br.readLine());
          arr[i][0] = st.nextToken();
          arr[i][1] = st.nextToken();
        }

        Arrays.sort(arr, (a, b) -> {
          int compare = Integer.compare(Integer.parseInt(a[0]), Integer.parseInt(b[0]));
          if (compare == 0) {
            return Integer.compare(Integer.parseInt(a[1]), Integer.parseInt(b[1]));
          }
          return compare;
        });

        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < N; i++) {
          sb.append(arr[i][0]).append(" ").append(arr[i][1]).append("\n");
        }
        bw.write(sb.toString());
        bw.close();
    }
}

 

 

 

 

람다 표현식

Arrays.sort(arr, (a, b) -> {
  int compare = Integer.compare(Integer.parseInt(a[0]), Integer.parseInt(b[0]));
  if (compare == 0) {
    return Integer.compare(Integer.parseInt(a[1]), Integer.parseInt(b[1]));
  }
  return compare;
});

 

ㄴ 람다 표현식을 사용하여 Comparator를 정의하고, Comparator 인터페이스의 compare 메서드를 구현합니다.

ㄴ (a, b)는 두 개의 비교 대상을 나타낸다.
ㄴ Integer.compare(Integer.parseInt(a[0]), Integer.parseInt(b[0]))은 x좌표의 값을 정수로 변환한 후에 x좌표 값을 비교한다.

ㄴ Integer.compare 메서드는 두 정수를 비교하여 오름차순으로 정렬하도록 도와준다.
ㄴ 이렇게 정의된 Comparator를 사용하여 Arrays.sort 메서드로 배열을 정렬하면 x좌표가 오름차순으로 정렬된다.

ㄴ 만약 x좌표 값이 같으면 compare 변수에 0이 저장되고, Integer.compare(Integer.parseInt(a[1]), Integer.parseInt(b[1]))를 통해 y좌표 값을 오름차순으로 비교한다.

ㄴ 최종적으로 compare 변수의 값을 반환하여 정렬 순서를 결정하도록 한다.

     ㄴ 여기서 compare 변수의 값은 int 타입이다. (Integer.compare 메서드의 반환값인 정수가 이 변수에 저장되기 때문)

     ㄴ 이 정수는 두 비교 대상이 동일하면 0, 첫 번째 인자가 작으면 음수, 첫 번째 인자가 크면 양수를 반환한다.

 

위 람다 표현식은 원래 아래와 같이 표현된다.

 

Arrays.sort(arr, new Comparator<String[]>() {
   @Override
    public int compare(String[] a, String[] b) {
        int compare = Integer.compare(Integer.parseInt(a[0]), Integer.parseInt(b[0]));
        if (compare == 0) {
            return Integer.compare(Integer.parseInt(a[1]), Integer.parseInt(b[1]));
        }
        return compare;
    }
});

 

ㄴ 이를 아래와 같이 삼항 연산자를 이용하여 표현할 수도 있다.

 

Arrays.sort(arr, new Comparator<String[]>() {
    @Override
    public int compare(String[] a, String[] b) {
        int compare = Integer.compare(Integer.parseInt(a[0]), Integer.parseInt(b[0]));
        return compare == 0 ? Integer.compare(Integer.parseInt(a[1]), Integer.parseInt(b[1])) : compare;
    }
});

 

 


 

 

문제점 : Arrays.sort 를 이용해서 정렬하고 이를 커스텀하여 비교하는 것까지는 생각했지만, 같을 경우 어떻게 비교할지에 대한 커스텀은 어떻게 하는지 몰랐다.

해결 방법 : x좌표의 값에 대해 Integer.compare를 이용하여 정렬을 하고, x좌표의 값 비교 시 값이 같다면 y좌표의 값을 비교하도록 Comparator를 정의하도록 했다.

깨달은 바 : Arrays.sort 를 이용하여 배열의 0번째 값을 비교하도록 정렬 기준을 만들어서 비교할 때, 값이 같을 경우 배열의 1번재 값을 비교하도록 정렬 기준을 만드는 방법을 알게되었다. 또한, Integer.compare 이용 시 두 비교 대상이 동일하면 0, 첫 번째 인자가 작으면 음수, 첫 번째 인자가 크면 양수를 반환한다는 것을 알게되었다. 앞으로도 Comparator를 정의하는 방식을 잘 이용해야겠다.