도현이네 반 학생 N명의 이름과 국어, 영어, 수학 점수가 주어진다. 이때, 다음과 같은 조건으로 학생의 성적을 정렬하는 프로그램을 작성하시오.
- 시간 제한 : 1초
- 메모리 제한 : 256MB
첫째 줄에 도현이네 반의 학생의 수 N (1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 한 줄에 하나씩 각 학생의 이름, 국어, 영어, 수학 점수가 공백으로 구분해 주어진다. 점수는 1보다 크거나 같고, 100보다 작거나 같은 자연수이다. 이름은 알파벳 대소문자로 이루어진 문자열이고, 길이는 10자리를 넘지 않는다.
문제에 나와있는 정렬 기준으로 정렬한 후 첫째 줄부터 N개의 줄에 걸쳐 각 학생의 이름을 출력한다.
문제를 해결하기 위해 주어진 조건대로 학생들을 정렬하여야 하므로 학생 정보를 저장할 클래스는 Comparable
인터페이스를 구현해야 합니다. 클래스를 구현하면 아래와 같습니다.
/**
* 학생 정보를 나타낼 클래스
* {@link Comparable} 인터페이스를 구현하여 정렬할 수 있도록 한다.
*/
static class Student implements Comparable<Student> {
String name;
int kor, math, eng;
public Student(String name, int kor, int eng, int math) {
this.name = name;
this.kor = kor;
this.eng = eng;
this.math = math;
}
/**
* @param other 비교할 다른 학생
* @return 현재 학생이 앞에 와야하면 양수,
* 다른 학생이 앞에 와야하면 음수, 둘 다 아닐 경우 0을 반환
*/
public int compareTo(Student other) {
if (this.kor == other.kor) {
if (this.eng == other.eng) {
if (this.math == other.math) {
// 이름은 오름차순
return this.name.compareTo(other.name);
}
// 수학 점수는 내림차순
return other.math - this.math;
}
// 영어 점수는 오름차순
return this.eng - other.eng;
}
// 국어 점수는 내림차순
return other.kor - this.kor;
}
}
java.util.Arrays
의 sort
를 이용하여 알맞은 순서로 학생들을 정렬 후 학생들의 이름을 출력하면 문제를 해결할 수 있습니다.
import java.io.*;
import java.util.*;
public class Main {
/**
* 학생 정보를 나타낼 클래스
* {@link Comparable} 인터페이스를 구현하여 정렬할 수 있도록 한다.
*/
static class Student implements Comparable<Student> {
String name;
int kor, math, eng;
public Student(String name, int kor, int eng, int math) {
this.name = name;
this.kor = kor;
this.eng = eng;
this.math = math;
}
/**
* @param other 비교할 다른 학생
* @return 현재 학생이 앞에 와야하면 양수,
* 다른 학생이 앞에 와야하면 음수, 둘 다 아닐 경우 0을 반환
*/
public int compareTo(Student other) {
if (this.kor == other.kor) {
if (this.eng == other.eng) {
if (this.math == other.math) {
// 이름은 오름차순
return this.name.compareTo(other.name);
}
// 수학 점수는 내림차순
return other.math - this.math;
}
// 영어 점수는 오름차순
return this.eng - other.eng;
}
// 국어 점수는 내림차순
return other.kor - this.kor;
}
}
static Student[] students;
static int n;
static StringBuilder sb = new StringBuilder();
public static void main(String[] args) throws Exception {
input();
func();
System.out.println(sb);
}
static void input() throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer tokenizer;
n = Integer.parseInt(br.readLine());
students = new Student[n];
for (int i = 0; i < n; ++i) {
tokenizer = new StringTokenizer(br.readLine());
students[i] = (
new Student(
tokenizer.nextToken(),
Integer.parseInt(tokenizer.nextToken()),
Integer.parseInt(tokenizer.nextToken()),
Integer.parseInt(tokenizer.nextToken())
)
);
}
}
static void func() {
// 정렬
Arrays.sort(students);
// 정렬 후 이름을 StringBuilder를 이용하여
// 순서대로 출력
for (Student st : students) {
sb.append(st.name).append('\n');
}
}
}
compareTo
를 구현할 때, 이번 문제의 경우에는 뺄셈 연산을 이용하여 구현하였지만 오버플로우가 발생하여 뺄셈으로 구현을 못하는 경우도 존재합니다. 그럴때는 compare
을 이용하여 구현하여야 합니다.