이차원 배열을 어떤 식으로 사용해야하나 고민을 하다가 정 모르겠어서 검색을 해보았다.
그 결과 이 문제는 Arrays.sort() 의 내부 동작원리를 알고, 그것을 확장하여 풀면 되는 문제임을 알았다.
위의 자바 API 에 나와있듯이 sort() 는 두 가지의 인자를 받을 수 있다.
첫번째는 제너릭타입의 객체배열(T[]), 두번째는 Comparator<? super T> c 이다. 첫번째 인자를 좀 더 자세히 보면, 만약 int[] 형 배열을 쓸 경우 T는 int 로 결정되고, Student[] 형태의 객체배열을 쓸 경우 T는 student로, 여기서는 int[][] 이차원 배열을 사용할 것이므로 T는 int[]가 된다.
두 번째 인자에서 <? super T> 는 상속관계에 있는 타입만 자료형으로 받겠다는 의미이고, 여기서는 Comparator의 compare 메소드를 오버라이딩하여 compare 메소드 안에 자신만의 비교 방법을 구현할 것이다.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;
import java.util.Stack;
public class Main {
static String answer = "";
public void solution() {
Scanner kb = new Scanner(System.in);
int n = kb.nextInt();
int[][]arr = new int[n][2];
for(int i=0;i<n;i++) {
for(int j=0;j<2;j++) {
arr[i][j] = kb.nextInt();
}
}
// Arrays.sort(arr,new Comparator<int[]>() {
// public int compare(int[] e1,int[] e2) {
// if(e1[0]==e2[0])
// return e1[1] - e2[1];
// else
// return e1[0] - e2[0];
// }
// });
// 위의 주석 코드를 람다식으로
Arrays.sort(arr,(e1,e2)-> {
if(e1[0]==e2[0])
return e1[1] - e2[1];
else
return e1[0] - e2[0];
});
for(int i=0;i<n;i++) {
System.out.println(arr[i][0]+" "+arr[i][1]);
}
// StringBuilder sb = new StringBuilder();
// for(int i=0;i<n;i++) {
// sb.append(arr[i][0]+" "+arr[i][1]).append('\n');
// }
}
public static void main(String[]args) {
new Main().solution();
}
}
아래 부분이 가장 중요하다.
sort()의 내부 동작 방식을 간단하게 보면,
두 원소를 뺐을 때 값이 양수이면 두 원소의 자리를 바꾸고,
음수이면 그대로 둔다.
Arrays.sort(arr,new Comparator<int[]>() {
public int compare(int[] e1,int[] e2) {
if(e1[0]==e2[0]) // x좌표가 같으면
return e1[1] - e2[1]; // y좌표를 비교한다.
else
return e1[0] - e2[0];
}
});
위 함수를 람다식으로 나타내면 더 편리하다.
람다식을 간단한 예제로 먼저 살펴보면,
// 람다식 X
int c = sum(a+b);
public int sum(int a, int b){
return a+b;
}
// 람다식 O
int c = (int a, int b) -> {return a+b; }
더 간결하다.
Arrays.sort(arr,(e1,e2)-> {
if(e1[0]==e2[0])
return e1[1] - e2[1];
else
return e1[0] - e2[0];
});
여기까지 해도 백준 문제풀이 통과는 가능하다.
하지만 좀 더 효율을 높이고 싶으면,
Scanner 대신에 BufferedReader를 사용하거나,
System.out.println() 대신에 StringBuilder 를 사용하면 된다. (주석부분참고)
cf. https://st-lab.tistory.com/110
[백준] 11650번 : 좌표 정렬하기 - JAVA [자바]
www.acmicpc.net/problem/11650 11650번: 좌표 정렬하기 첫째 줄에 점의 개수 N (1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 N개의 줄에는 i번점의 위치 xi와 yi가 주어진다. (-100,000 ≤ xi, yi ≤ 100,000) 좌표는 항
st-lab.tistory.com
sort() 확장 방식과 람다식 기억해두자!
'백준 문제풀이' 카테고리의 다른 글
백준 15439번 : 베라의 패션 (0) | 2023.07.19 |
---|---|
백준 9372번: 상근이의 여행 - 최소 신장 트리 성질 이용 (0) | 2023.07.05 |
백준 2751번 : 수 정렬하기2 - 시간초과 문제해결 - Collections.sort() 사용하기 (0) | 2023.06.29 |
[python] 백준 1924: 2007년 (0) | 2021.06.05 |
[python] 백준 1157번: 단어공부 (0) | 2021.05.14 |
댓글