https://www.acmicpc.net/problem/1431
코드설명
정렬 문제입니다.
문제에서 어떻게 정렬을 할까 고민했습니다.
1. 첫번쨰 방법은 Comparator<String> 를 활용한 방식입니다.
2. 두번쨰 방법은 Comaprable<Node>를 활용한 방식입니다.
저는 주로 객체를 생성하여 하는 방식으로 진행하므로, 두번쨰 방법을 선호합니다.
또, 문제에서 주어진 조건을 모두 직접 구현해도 되지만, Integer.compare(A, B) : A, B를 오름차순으로 정렬.
String,compareTo(String2) : 오름차순으로 정렬.
을 통해 오름차순으로 손쉽게 정렬할 수 있습니다.
만약, 내림차순으로 정렬하고 싶다면, 매개변수의 순서를 바꿔주면 해결됩니다.
이런 함수를 적용해서 코드작성시간을 줄이는 것이 좋습니다.
코드
package Main;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.StringTokenizer;
public class Main {
public static int N, T, M;
public static int answer = 0;
public static ArrayList<Node> arr = new ArrayList<>();
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
for(int i=0;i<N;i++) {
st = new StringTokenizer(br.readLine());
String a = st.nextToken();
arr.add(new Node(a));
}
Collections.sort(arr);
for(int i=0;i<N;i++) {
System.out.println(arr.get(i).str);
}
}
private static class Node implements Comparable<Node>{
String str;
public Node(String str) {
this.str = str;
}
@Override
public int compareTo(Node other) {
//A와 B의 길이가 다르면, 짧은 것이 먼저온다.
if(this.str.length() > other.str.length()) {
return 1;
}
//만약, 서로의 길이가 같다면, A의 모든 자리수의 합과 B의 모든 자리수의 합을 비교해서 작은합을 가지는 것이 먼저온다.(숫자인것만 더한다.)
else if(this.str.length() == other.str.length()) {
int ASum = getSum(this.str);
int BSum = getSum(other.str);
if(ASum > BSum) {
return 1;
}
//만약, 1, 2 번 둘 조건으로도 비교할 수 없으면, 사전순으로 비교한다.
//숫자가 알파벳보다 사전순으로 작다.
else if(ASum == BSum) {
return this.str.compareTo(other.str);
}else if(ASum < BSum) {
return -1;
}
}else if(this.str.length() < other.str.length()) {
return -1;
}
return 0;
}
private int getSum(String a) {
int sum = 0;
for(int i=0; i<a.length();i++) {
if(a.charAt(i) >= '0' && a.charAt(i) <='9') {
sum += a.charAt(i) - '0';
}
}
return sum;
}
}
}
Integer.compare와 str.compareTo(str2) 를 통해서 더 깔끔한 코드입니다.
package Main;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.StringTokenizer;
public class Main {
public static int N, T, M;
public static int answer = 0;
public static ArrayList<Node> arr = new ArrayList<>();
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
for(int i=0;i<N;i++) {
st = new StringTokenizer(br.readLine());
String a = st.nextToken();
arr.add(new Node(a));
}
Collections.sort(arr);
for(int i=0;i<N;i++) {
System.out.println(arr.get(i).str);
}
}
private static class Node implements Comparable<Node>{
String str;
public Node(String str) {
this.str = str;
}
@Override
public int compareTo(Node other) {
//길이에 따른 오름차순 정렬합니다.
if(this.str.length() != other.str.length())
return Integer.compare(this.str.length(), other.str.length());
int ASum = getSum(this.str);
int BSum = getSum(other.str);
if(ASum != BSum)
return Integer.compare(ASum, BSum);
return this.str.compareTo(other.str);
}
private int getSum(String a) {
int sum = 0;
for(int i=0; i<a.length();i++) {
if(a.charAt(i) >= '0' && a.charAt(i) <='9') {
sum += a.charAt(i) - '0';
}
}
return sum;
}
}
}
Comparator<String>을 활용하여 굳이 Node객체를 생성안합니다.
package Main;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.StringTokenizer;
public class Main {
public static int N;
public static ArrayList<String> arr = new ArrayList<>();
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
for(int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
String a = st.nextToken();
arr.add(a);
}
Collections.sort(arr, new CustomComparator());
for(int i = 0; i < N; i++) {
System.out.println(arr.get(i));
}
}
private static class CustomComparator implements Comparator<String> {
@Override
public int compare(String a, String b) {
// 길이에 따른 오름차순 정렬
if(a.length() != b.length())
return Integer.compare(a.length(), b.length());
// 숫자 합 비교
int sumA = getSum(a);
int sumB = getSum(b);
if(sumA != sumB)
return Integer.compare(sumA, sumB);
// 사전순 비교
return a.compareTo(b);
}
private int getSum(String s) {
int sum = 0;
for(int i = 0; i < s.length(); i++) {
if(s.charAt(i) >= '0' && s.charAt(i) <= '9') {
sum += s.charAt(i) - '0';
}
}
return sum;
}
}
}
Comparator와 익명클래스를 함꼐 구현한다면,
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.StringTokenizer;
public class Main {
public static int N;
public static ArrayList<String> arr = new ArrayList<>();
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
for(int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
String a = st.nextToken();
arr.add(a);
}
Collections.sort(arr, new Comparator<String>() {
@Override
public int compare(String a, String b) {
// 길이에 따른 오름차순 정렬
if(a.length() != b.length())
return Integer.compare(a.length(), b.length());
// 숫자 합 비교
int sumA = getSum(a);
int sumB = getSum(b);
if(sumA != sumB)
return Integer.compare(sumA, sumB);
// 사전순 비교
return a.compareTo(b);
}
private int getSum(String s) {
int sum = 0;
for(int i = 0; i < s.length(); i++) {
if(s.charAt(i) >= '0' && s.charAt(i) <= '9') {
sum += s.charAt(i) - '0';
}
}
return sum;
}
});
for(int i = 0; i < N; i++) {
System.out.println(arr.get(i));
}
}
}
만약 사전순 정렬을 직접 구현하고싶다면, 아래와 같이 구현할 수 있습니다.
private int customCompare(String a, String b) {
int len = Math.min(a.length(), b.length());
for (int i = 0; i < len; i++) {
char charA = a.charAt(i);
char charB = b.charAt(i);
if (charA != charB) {
// 숫자가 알파벳보다 사전순으로 작음
if (Character.isDigit(charA) && !Character.isDigit(charB)) {
return -1;
} else if (!Character.isDigit(charA) && Character.isDigit(charB)) {
return 1;
} else {
return Character.compare(charA, charB);
}
}
}
// 여기까지 왔다면 모든 문자가 같다는 의미이므로 0을 반환
return 0;
}
'알고리즘 > 백준' 카테고리의 다른 글
[백준] 2108 통계학 - 구현(Implementation) + 정렬(Sorting) JAVA (0) | 2024.07.28 |
---|---|
[백준] 1485 정사각형 - 기하학(Geometry) + 정렬(Sorting) JAVA (0) | 2024.07.27 |
[백준] 9657 돌 게임 3 - 동적계획법(Dynamic Programming, DP) + 게임이론(Game Theory) JAVA (0) | 2024.07.26 |
[백준] 9656 돌 게임 2 - 동적계획법(Dynamic Programming, DP) + 게임이론(Game Theory) JAVA (0) | 2024.07.26 |
[백준] 8394 악수 - 동적계획법(DP, Dynamic Programming) + 수학(Math) JAVA (0) | 2024.07.24 |