본문 바로가기

Algorithm

11651 좌표 정렬하기 2 / 정렬 / 자바 Arrays.sort()

n = int(input())
arrays = []

for _ in range(n):
    x, y = map(int, input().split())
    arrays.append((x, y))

arrays.sort(key=lambda p: (p[1], p[0]))

for x, y in arrays:
    print(x, y)

 

Sort

  • sort의 기본 -> 오름차순 정렬
  • key는 정렬 기준을 반환하는 함수
  • lambda : 인수1, 인수2, ...: 반환값
  • key : [(3, 1), (2, 2), (1, 2), (2, 3), (1, 3)] -> 각각 생성된 key값에 의해서 오름차순으로 정렬되는 것

 

자바

  • e1[0] = 1, e2[0] = 2일 때:
    • e1[0] - e2[0]은 1 - 2 = -1
    • -1은 음수이므로, e1이 e2보다 작다고 판단하고, e1이 먼저 오도록 정렬
  • e1[0] = 2, e2[0] = 1일 때:
    • e1[0] - e2[0]은 2 - 1 = 1
    • 1은 양수이므로, e1이 e2보다 크다고 판단하고, e2가 먼저 오도록 정렬

자바의 Arrays.sort() 구현 원리

  1. 기본적으로 오름차순 정렬을 할 때:
    • 비교 함수가 -1을 반환하면 첫 번째 요소가 더 작은 것으로 간주되어 앞에 옴
    • 비교 함수가 1을 반환하면 두 번째 요소가 더 작은 것으로 간주되어 앞에 옴
    • 0을 반환하면 두 요소가 같으므로 순서를 그대로 유지
  2. Comparator 인터페이스에서의 compare() 메서드는 두 객체를 비교한 후, -1, 0, 1 중 하나를 반환:
    • -1: 첫 번째 객체가 두 번째 객체보다 작다 (즉, 앞에 오게 됨)
    • 1: 첫 번째 객체가 두 번째 객체보다 크다 (즉, 뒤에 오게 됨)
    • 0: 두 객체가 같다 (순서를 변경하지 않음)

자바의 Arrays.sort()는 기본적으로 비교값이 음수일 때 첫 번째 값이 더 작은 것으로 간주하여 먼저 오게 하고, 양수일 때는 두 번째 값이 더 작은 것으로 간주하여 먼저 오게 함 -> 자바의 오름차순 정렬에 대한 표준적인 방식

import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int N = in.nextInt();
        int[][] arr = new int[N][2];

        // 점 좌표 입력 받기
        for (int i = 0; i < N; i++) {
            arr[i][0] = in.nextInt();  // x 좌표
            arr[i][1] = in.nextInt();  // y 좌표
        }

        // 정렬: y 좌표가 같으면 x 좌표를 비교
        Arrays.sort(arr, new Comparator<int[]>() {
            @Override
            public int compare(int[] e1, int[] e2) {
                if (e1[1] == e2[1]) {
                    return e1[0] - e2[0];  // y 값이 같으면 x 값을 비교
                } else {
                    return e1[1] - e2[1];  // y 값으로 오름차순 정렬
                }
            }
        });

        // 정렬된 점 출력
        for (int i = 0; i < N; i++) {
            System.out.println(arr[i][0] + " " + arr[i][1]);
        }
    }
}

 

람다로 변경시에 compare의 메서드를 오버라이딩 한 것이라는 걸 아는 이유

  • 람다를 사용하면 객체를 명시적으로 선언하지 않고도 인터페이스 메서드를 구현 가능 -> 람다는 익명 클래스처럼 동작
  • 자바에서는 Comparator 인터페이스를 구현하는 람다 표현식이 필요할 때 자동으로 그 타입을 추론 
  • 즉, Comparator가 필요한 자리에 람다를 넣으면 자바 컴파일러가 이를 Comparator의 구현으로 자동 인식
Arrays.sort(arr, (e1, e2) -> {
			if(e1[0] == e2[0]) {
				return e1[1] - e2[1];
			} else {
				return e1[0] - e2[0];
			}
		});