[백준] 11651번 : 좌표 정렬하기 2 - JAVA [자바]
- 문제
좌표 정렬하기 (11650번) 문제를 풀었다면 매우 쉬운 문제다.
알고리즘은 따로 설명 안할테니 아래 링크를 참고해주시면 된다.
우리가 주의해야 할 점은 이전 문제와 달리 두 번째 원소를 기준으로 오름차순으로 정렬하면서 만약 두 번째 원소가 같을 경우 첫 번째 원소를 오름차순으로 정렬해야한다는 점이다.
여기서 우리가 고려해 볼 수 있는 방법은 2차원 배열에 입력받은 값을 넣어줄 때, 첫 번째 원소값은 배열의 두 번째 원소값으로, 두 번째 원소 값을 배열의 첫 번째 원소 값으로 넣어준 뒤 이전 문제와 같은 알고리즘으로 sort 를 lambda 식으로 compare 메소드를 확장 구현하여 정렬하는 방법이 있고, compare 메소드에서 비교를 두 번째 원소를 기준으로 변경하여 구현하는 방법이 있다.
가장 쉬운 방법은 두 원소의 위치를 바꾸어 배열에 넣어주는 것이니 이 방법을 사용하여 풀어보도록 하겠다.
만약 Comparator(compare메소드) 에 대해 원리를 이해하고 싶다면 아래 글을 참고하시길 바란다.
- 3가지 방법을 이용하여 풀이한다.
Scanner + System.out.print() 반복출력
Scanner + StringBuilder
BufferedReader + StringBuilder
이렇게 3가지 입출력 방법을 통해 풀어보고자 한다.
- 풀이
- 방법 1 : [Scanner + System.out.println]
import java.util.Scanner;
import java.util.Arrays;
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][1] = in.nextInt();
arr[i][0] = in.nextInt();
}
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][1] + " " + arr[i][0]);
}
}
}
이전 문제의 방법 1 와 코드가 거의 비슷하다. 입출력만 반대로 해주면 된다.
- 방법 2 : [Scanner + StringBuilder]
출력을 반복해서 호출해주는 방법이 아닌 하나의 문자열로 묶은 뒤 한 번에 출력해주는 방식이다.
물론 BufferedWriter 으로 해도 되지만, 필자는 StringBuilder 가 편하기에.. 물론 상황에 따라 때론 StringBuilder 가 우월할 때도 있다.
import java.util.Scanner;
import java.util.Arrays;
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][1] = in.nextInt();
arr[i][0] = in.nextInt();
}
Arrays.sort(arr, (e1, e2) -> {
if(e1[0] == e2[0]) {
return e1[1] - e2[1];
} else {
return e1[0] - e2[0];
}
});
StringBuilder sb = new StringBuilder();
for(int i = 0; i < N; i++) {
// 위치 주의
sb.append(arr[i][1] + " " + arr[i][0]).append('\n');
}
System.out.println(sb);
}
}
- 방법 3 : [BufferedReader + StringBuilder]
방법 2에서 입력방법을 바꾼 것이다. 두 말할 것도 없이 당연 Scanner 보다 BufferedReader 가 성능이 더 좋다.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
int[][] arr = new int[N][2];
StringTokenizer st;
for(int i = 0; i < N; i++) {
// 위치 주의
st = new StringTokenizer(br.readLine());
arr[i][1] = Integer.parseInt(st.nextToken());
arr[i][0] = Integer.parseInt(st.nextToken());
}
Arrays.sort(arr, (e1, e2) -> {
if(e1[0] == e2[0]) {
return e1[1] - e2[1];
} else {
return e1[0] - e2[0];
}
});
StringBuilder sb = new StringBuilder();
for(int i = 0 ; i< N ; i++) {
// 위치 주의
sb.append(arr[i][1] + " " + arr[i][0]).append('\n');
}
System.out.println(sb);
}
}
- 성능
위에서 부터 순서대로
채점 번호 : 20399255 - 방법 3 : BufferedReader + StringBuilder
채점 번호 : 20399241 - 방법 2 : Scanner + StringBuilder
채점 번호 : 20399238 - 방법 1 : Scanner + System.out.println
입출력의 방법에 따라 시간이 많이 차이 나는 것을 볼 수 있다.
- 정리
오늘은 사실상 좌표정렬하기 첫 번째 문제를 거의 그대로 쓰면 되기 때문에 어려운 문제는 아니였다.
오늘의 결론이라 함은 BufferedReader 와 StringBuilder (또는 BufferedWriter) 을 쓰자... 정도 되려나. 그리고 위와 같이 sort 메소드를 확장 구현 하는 방법은 반드시 익혀두자. 이 방법만 제대로 알아도 꽤 써먹을 일이 많다.
'JAVA - 백준 [BAEK JOON] > 정렬' 카테고리의 다른 글
[백준] 10814번 : 나이순 정렬 - JAVA [자바] (29) | 2020.06.20 |
---|---|
[백준] 1181번 : 단어 정렬 - JAVA [자바] (41) | 2020.06.19 |
[백준] 11650번 : 좌표 정렬하기 - JAVA [자바] (49) | 2020.06.10 |
[백준] 1427번 : 소트인사이드 - JAVA [자바] (12) | 2020.06.03 |
[백준] 2108번 : 통계학 - JAVA [자바] (43) | 2020.06.01 |