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;
}

 

+ Recent posts