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 |