10825번: 국영수
첫째 줄에 도현이네 반의 학생의 수 N (1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 한 줄에 하나씩 각 학생의 이름, 국어, 영어, 수학 점수가 공백으로 구분해 주어진다. 점수는 1보다 크거나 같고, 1
www.acmicpc.net
📌 Interface Comparator
: 기본적인 정렬 방법인 오름차순 정렬을 내림차순으로 정렬할 때 많이 사용한다.
👉 Comparator Interface를 implements 후 compare() method를 오버라이드한 myComparator Class를 작성한다.
📌 자바 문자열 비교 함수 Compare(), CompareTo()
1️⃣ compareTo()
: 문자열의 사전순 값을 비교하여 그에 해당되는 int 값을 리턴한다.
예를 들어서 A > B 라고 한다면,
- A = A → 0 (동일한 경우, 리턴값 0 반환)
- A > B → 1 (좌측 값이 큰 경우 1 반환)
- B > A → -1 (좌측 값이 작은 경우 -1 반환)
public void test() {
Stirng str1 = "AA";
String str2 = "AA";
String str3 = "CC";
System.out.println(str1.compareTo(str2)); // 결과 0
System.out.println(str2.compareTo(str3)); // 결과 -1
System.out.println(str3.compareTo(str2)); // 결과 1
}
2️⃣ compare()
: Comparator 인터페이스를 구현할 때 작성해야하는 메소드.
실제로 구현할 때 comapre()에 2개의 인자를 넘겨 내부에 구현에 따라 int 결과 값을 리턴한다.
@Override
public int compare(인자1, 인자2) {
if(인자1 > 인자2) {
return 1;
} else if (인자1 < 인자2) {
return -1;
} else {
return 0;
}
}
3️⃣ 두 메소드의 비슷한 점과 차이점
1) 비슷한 점
- 둘 다 두 객체를 비교하는 맞춤 방식이다.
- 둘 다 두 객체 간의 관계를 설명하는 int를 반환한다.
2) 차이점
- compare() method는 Comparator Interface를 구현할 때 구현해야하는 메소드다.
- 메소드에 두 개의 객체를 전달할 수 있으며, 관계를 설명하는 int를 반환한다.
📌 StringBuilder
: 문자열을 버퍼에 담아 그 안에서 추가 수정 삭제 작업을 할 수 있도록 도와주는 클래스
👉 String 클래스는 고정 길이로 되어있기 때문에 한 번 작성한 문자열 뒤에 문자열을 추가하게 되면 새로운 문자열을 작성하게 된다.
👉 이에 비해 StringBuilder 클래스는 가변길이의 문자열을 사용하는 클래스로 문자를 추가해도 새로운 오브젝트를 작성하지 않고
문자열을 추가가 가능하므로 문자열 결합하는 처리가 많은 경우 효율적이다.
🔫 풀이방법
BufferedReader + StringTokenizer (문자열 분리) + StringBuilder 를 사용하여 풀어보았다.
Compartor 안에 다중 조건문으로 작성하여 정렬 할 수 있다.
이 때, return 값에서 x,y 부분을 반대로 바꿔주면 [ 오름차순 <-> 내림차순 ] 으로 바꿀 수 있다.
✖︎ 주의할 점
Integer.compare(int타입), Integer.parseInt(String타입) 의 인자값의 타입형을 확인하여 문자열을 변환해 주어야 한다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Comparator;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
// 10825번 국영수
// 오름차순 (작은 수 -> 큰 수) / 내림차순 (큰 수 -> 작은 수)
//1. 국어점수가 감소하는 순서로 -> 내림차순
//2. 국어점수가 같으면 영어 점수가 증가하는 순서로 -> 오름차순
//3. 국어점수와 영어점수가 같으면 수학 점수가 감소하는 순서로 -> 내림차순
//4. 모든 점수가 같으면 이름이 사전 순으로 증가하는 순서로 -> 오름차순 / 아스키코드는 대소문자 순서 반대
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
String[][] arr = new String[N][4];
for(int i = 0; i<N; i++) {
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
arr[i][0] = st.nextToken(); //이름
arr[i][1] = st.nextToken(); //국어점수
arr[i][2] = st.nextToken(); //영어점수
arr[i][3] = st.nextToken(); //수학점수
}
Arrays.sort(arr, new Comparator<String[]>() {
@Override
public int compare(String[] o1, String[] o2) {
// 조건문을 걸어준다.
// 기본 오름차순 기준 / 내림차순 할 시 반대로 입력
// 오름차순 <-> 내림차순
if(Integer.parseInt(o1[1]) == Integer.parseInt(o2[1])) {
if(Integer.parseInt(o1[2]) == Integer.parseInt(o2[2])) {
if(Integer.parseInt(o1[3]) == Integer.parseInt(o2[3])) {
// 국영수 점수가 같을 때 오름차순
return o1[0].compareTo(o2[0]);
}
// 국영 점수가 같을 때 수학 내림차순
return Integer.compare(Integer.parseInt(o2[3]), Integer.parseInt(o1[3]));
}
//국어 점수가 같을 때 영어 오름차순
return Integer.compare(Integer.parseInt(o1[2]), Integer.parseInt(o2[2]));
}
// 국어 내림차순
return Integer.compare(Integer.parseInt(o2[1]), Integer.parseInt(o1[1]));
}
});
StringBuilder sb = new StringBuilder();
for(int i=0; i<N; i++) {
sb.append(arr[i][0]).append('\n');
}
System.out.println(sb);
}
}
댓글