백준 11650번
https://www.acmicpc.net/problem/11650
2차원 평면 위의 점 N개가 주어진다. 좌표를 x좌표가 증가하는 순으로, x좌표가 같으면 y좌표가 증가하는 순서로 정렬한 다음 출력하는 프로그램을 작성하시오.
첫째 줄에 점의 개수 N (1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 N개의 줄에는 i번점의 위치 xi와 yi가 주어진다. (-100,000 ≤ xi, yi ≤ 100,000) 좌표는 항상 정수이고, 위치가 같은 두 점은 없다.
이름만 들어도 어떤 문제인지 알 수 있다.
좌표정렬하기 그냥 정렬문제이다.
근데 어렵다.. x좌표와 y좌표를 활용하라는 내용을 보니까 2차원 배열을 써야 될 것 같은데 한참 고민하다 다른 분들의 코드를 참조하기로 했다.
1. https://st-lab.tistory.com/110
2. https://ehdals9412.tistory.com/25
처음에 2차원 배열을 활용하는 것 까지는 맞았다.
문제는 내가 2차원 배열은 정렬을 할 줄 모른다는 것..
첫번째는 Arrays.sort()에 람다식을 확장 시켜주는 것이다..
먼저 입력받는 값 들로 2차원 배열을 생성하고,
Arrays.sort(arr, (arr_1, arr_2) -> {}
의 형식으로 기존의 Arrays.sort()
를 조금 수정하는 것(?) 이라고 해도 될 것 같다.
2차원 배열의 x값 끼리 먼저 비교 후 x값이 같을 경우 y값을 기준으로 하기 때문에
이런 비교 조건을 우리가 만들어 주는 것이다.
arr
배열에서 첫번째는 arr_1
두번째는 arr_2
로 해서
arr_1[0]
과 arr_2[0]
2개가 x값 이므로 비교해서 같을 경우
arr_1[1]
과 arr_2[1]
가 y값 이므로 두 값을 비교한다.
여기서 arr_1[1]
과 arr_2[1]
을 빼서 arr_1[1]
이 더 클 경우 위치를 바꾸게 된다.
쉽게 말해서 return 되는 값이
음수 일 경우 : 위치를 바꾸지 않음
양수일 경우 : 위치를 바꿈
이라는 조건으로 가게 된다.
이 방식으로 2차원 배열을 정렬하면 정상적인 출력값을 얻을 수 있다.
두번째 방식은 비슷하지만 람다식을 사용하지 않고 조금 더 기초적으로 접근 한 방식이다.
당연히 첫번째 방법이 더 빠르고 간결하지만 그래도 동작방식의 기초를 알고가는 것은 굉장히 중요하기 때문에 따로 찾아보았다.
여기서도 Arrays.sort()
까지는 똑같지만 Comparator
인터페이스를 가져와서 수정한다.
Comparator
의 compare
메소드를 오버라이드 해서 재정의 해주는 것이다.
원래 Arrays.sort()
에서 mergesort에서도 compare
메소드를 사용하기 때문에 이 방법이 가능하다.
이 부분에서 몰랐는데 새로 알게 된 점은 객체형의 Integer를 비교할 때는 == 이 아닌 equals를 사용해야 된다는 것을 알게 됬다.
정렬을 공부하며 비교과정까지 공부하게 되고 알게 되었지만 Comparator 진짜 중요하고 유용한 것 같다.
람다식은 처음 접해 봤는데, 간결하고 도움도 많이 될 것 같다는 생각이 든다.
앞으로 좀 파볼까?
import java.util.*; import java.io.*; public class Main { static int arr[][]; public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringBuilder sb = new StringBuilder(); int N = Integer.parseInt(br.readLine()); arr = new int [N][2]; for(int i=0; i<N; i++) { StringTokenizer st = new StringTokenizer(br.readLine()); arr[i][0] = Integer.parseInt(st.nextToken()); arr[i][1] = Integer.parseInt(st.nextToken()); } Arrays.sort(arr, (arr_1, arr_2) -> { if(arr_1[0] == arr_2[0]) { return arr_1[1] - arr_2[1]; } else { return arr_1[0] - arr_2[0]; } }); for(int i=0; i<N; i++) { sb.append(arr[i][0] + " " + arr[i][1]).append('\n'); } System.out.println(sb); } }
import java.io.*; import java.util.*; import java.util.Comparator; public class Main { public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = null; StringBuilder sb = new StringBuilder(); int N = Integer.parseInt(br.readLine()); Integer arr[][] = new Integer[N][2]; for(int i=0; i<N; i++) { st = new StringTokenizer(br.readLine()); arr[i][0] = Integer.parseInt(st.nextToken()); arr[i][1] = Integer.parseInt(st.nextToken()); } Arrays.sort(arr, new Comparator<Integer[]>() { @Override public int compare(Integer[] o1, Integer[] o2) { if(o1[0].equals(o2[0])) { return o1[1] - o2[1]; } else { return o1[0] - o2[0]; } } }); for(int i=0; i<N; i++) { sb.append(arr[i][0] + " " + arr[i][1]).append('\n'); } System.out.println(sb); } }