[Algorithm/Java] 정렬 정리 (백준 10814, 11650, 1181번)
🎯 정렬 정리
자바에서 정렬은 크게 3가지 방식으로 나뉜다.
정렬 기준 | 사용하는 방식 | 메서드 예시 | 백준 문제 | 해석 |
---|---|---|---|---|
기준 1개 (숫자) | 단일 기준 정렬 | Comparator.comparingInt() |
10814 | 비교기야, 정수형을 기준으로 비교 좀 해줘! |
기준 2개 이상 | 복합 조건 정렬 | (a, b) -> {...} + Integer.compare() |
11650 | 두 정수 a, b를 비교해서 누가 더 작은지 알려줘 |
문자열 사전 순 | 문자열 비교 | compareTo() |
1181 | 이 객체가 상대 객체와 비교했을 때 앞이냐 뒤냐를 알려줘 |
// 1개 기준
Arrays.sort(arr, Comparator.comparingInt(a -> a[0]));
// 2개 기준
Arrays.sort(arr, (a, b) -> {
if (a[0] == b[0]) return Integer.compare(a[1], b[1]);
return Integer.compare(a[0], b[0]);
});
/* 문자열 정렬 */
// (List<String>인 경우)
Collections.sort(list, (s1, s2) -> {
if (s1.length() != s2.length()) return s1.length() - s2.length(); // 길이 오름차순
return s1.compareTo(s2); // 길이 같으면 사전순
});
// String[]인 경우
Arrays.sort(arr, (s1, s2) -> {
if (s1.length() != s2.length()) return s1.length() - s2.length(); // 길이 오름차순
return s1.compareTo(s2); // 길이 같으면 사전순
});
📌 백준 10814번 - 나이순 정렬
📝 조건
- 나이를 기준으로 오름차순 정렬
- 나이가 같으면 먼저 가입한 사람이 먼저 출력
Arrays.sort(arr, Comparator.comparingInt(a -> Integer.parseInt(a[0])));
📥 입출력 예시
입력
3
21 Junkyu
21 Dohyun
20 Sunyoung
출력
20 Sunyoung
21 Junkyu
21 Dohyun
🔍 문제 풀이
배열 정렬 메서드
Arrays.sort()
는 배열을 정렬할 때 쓰는 메서드- 첫 번째 인자는 정렬할 배열이고, 두 번째는 정렬 방법(기준)을 설정하는 Comparator
- 예를 들어, 내림차순으로 정렬하고 싶을 땐 아래와 같이 하면 됨
Arrays.sort(arr, Comparator.reverseOrder());
Comparator
- Comparator는 두 객체를 비교해 정렬 순서를 결정 (뜻: Comparator - 비교기)
comparingInt()
메서드는 정수값을 비교할 때 쓰이며, 정수형으로 변환된 값을 기준으로 정렬 (뜻: comparing - 비교하는)
람다 표현식
(a -> Integer.parseInt(a[0]))
- a는 배열의 각 요소 (
arr[i]
)로, 여기서는 String[] 타입 (arr의 타입이String[][]
이기 때문) - 예를 들어 {나이, 이름} 형태
- 따라서
a[0]
을 기준으로 정렬하려면Integer.parseInt(a[0])
는 각 요소의 첫 번째 항목(나이)을 정수로 변환하여 비교 기준으로 사용
💻 전체 코드
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));
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(); // age
arr[i][1] = st.nextToken(); // name
}
// 나이순으로 정렬, 같은 나이면 입력 순서 유지 (안정정렬)
Arrays.sort(arr, Comparator.comparingInt(a -> Integer.parseInt(a[0])));
// 결과 출력
StringBuilder sb = new StringBuilder();
for(String[] person : arr) { // person: 각 사람의 [나이, 이름] 정보를 담은 배열 (e.g., person = ["21", "Junkyu"])
sb.append(person[0]).append(" ").append(person[1]).append("\n");
}
System.out.println(sb);
}
}
arr가 2차원 배열 (String[][])
이면, arr의 각 요소는 1차원 배열 (String[])
📌 백준 11650번 - 좌표 정렬하기
📝 조건
- 2차원 평면 위에 있는 N개의 점을 x좌표 오름차순으로 정렬
- x좌표가 같은 경우 y좌표 오름차순
Arrays.sort(arr, (a, b) -> {
if (a[0] == b[0]) return Integer.compare(a[1], b[1]);
return Integer.compare(a[0], b[0]);
});
- 기준이 2개 이상이므로
comparingInt()
는 불가 int[][]
배열에서는Integer.compare()
를 사용하여 람다식 구성
📥 입출력 예시
입력
5
3 4
1 1
1 -1
2 2
3 3
출력
1 -1
1 1
2 2
3 3
3 4
🔍 문제 풀이
Comparator 람다식에서 a, b는 뭘까?
아래에서 a, b는 arr 배열 안의 두 요소를 비교하기 위해 꺼낸 값
Arrays.sort(arr, (a, b) -> {
if (a[0] == b[0]) return Integer.compare(a[1], b[1]);
return Integer.compare(a[0], b[0]);
});
만약 arr이 이렇게 생긴 2차원 배열이라면
int[][] arr = {
{1, 2},
{3, 4},
{1, -1}
};
a, b는 이 배열에서 하나씩 꺼낸 {1, 2}
, {3, 4}
같은 int[] (좌표 한 쌍) 을 의미
즉,
- a → 비교할 첫 번째 점 (ex:
{1, 2}
) - b → 비교할 두 번째 점 (ex:
{3, 4}
) - a[0], b[0]은 각 점의 x좌표
- a[1], b[1]은 각 점의 y좌표를 의미
💻 전체 코드
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));
int n = Integer.parseInt(br.readLine());
int[][] 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()); // x
arr[i][1] = Integer.parseInt(st.nextToken()); // y
}
// 여기가 핵심
Arrays.sort(arr, (a, b) ->{
if(a[0] == b[0]) return Integer.compare(a[1], b[1]);
return Integer.compare(a[0], b[0]);
});
// StringBuilder 사용하면 더 빠름
StringBuilder sb = new StringBuilder();
for(int[] item: arr){
sb.append(item[0]).append(" ").append(item[1]).append("\n");
}
System.out.println(sb);
}
}
📌 백준 1181번 - 단어 정렬
📎 https://www.acmicpc.net/problem/1181
📝조건
- 길이 오름차순
- 길이 같으면 사전 순
Collections.sort(list, (s1, s2) -> {
if (s1.length() != s2.length()) return s1.length() - s2.length();
return s1.compareTo(s2);
});
- 문자열의 길이 비교 + 사전순 정렬을 함께 적용
- 중복 제거를 위해
Set
활용 후List
로 변환하여 정렬
📥 입출력 예시
입력
13
but
i
wont
hesitate
no
more
no
more
it
cannot
wait
im
yours
출력
i
im
it
no
but
more
wait
wont
yours
cannot
hesitate
🔍 문제 풀이
HashSet
으로 중복을 제거하고, ArrayList로 변환- 길이 확인 후
compareTo
로 사전순 정렬
💻 전체 코드
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));
int n = Integer.parseInt(br.readLine());
Set<String> set = new HashSet<>();
for(int i=0; i<n; i++){
set.add(br.readLine());
}
List<String> list = new ArrayList<>(set);
Collections.sort(list, (s1, s2)->{
if(s1.length() != s2.length()){
return s1.length() - s2.length(); // 길이 짧은 순
} else{
return s1.compareTo(s2); // 사전 순
}
});
StringBuilder sb = new StringBuilder();
for(String word:list){
sb.append(word).append("\n");
}
System.out.println(sb);
}
}
댓글남기기