프로그래머스 [3차] 파일명 정렬
프로그래머스 가장 큰 수
백준 가장 높은 탑 (2655번)
백준 좌표 정렬하기 2 (11651)
오늘 Comparator 문제를 풀었습니다.
풀면서 이 부분을 정리하면 좋겠다는 생각이 들어 정리해보려고 합니다.
Comparator와 Comparable는 모두 인터페이스이고
용도는 비슷하지만 사용하는 방법이 조금 다릅니다.
Comparator의 compare(Object o1, Object o2) 두 개의 매개변수를 통해 매개변수끼리 비교하고 Comparable의 compareTo(Object o) 한 개의 매개변수를 자신과 비교합니다.
둘 중에 하나를 선택해서 정렬할 때 사용하면 됩니다.
저는 Comparator의 compare를 사용하는게 더 익숙해서 정렬을 할 때는 compare()메서드를 오버라이딩해서 진행합니다.
Comparator<String> comp = new Comparator<String>() {
public int compare(String s1,String s2){
return s1.length()-s2.length();
};
라고 할 때 반환값이 음수와 0인 경우는 들어온 순서를 유지하고 양수인 경우 자리 교환이 일어납니다.
보통 응용해서 문제를 내는데 오늘 푼 파일명 정렬은 추가로 "사전순"이라는 방법을 문제에 넣었습니다.
사전순으로 정렬할 때는 compare() 메서드 안에 compareTo() 메서드를 활용합니다.
"AA".compareTo("BB"); //음수
"BB".compareTo("AA"); //양수
"AA".compareTo("AA"); //0
따라서 오늘 푼 파일명 정렬의 풀이는 아래와 같습니다.
import java.util.*;
class Solution {
public String[] solution(String[] files) {
//파일 저장소 서버 관리
//이름 순으로 정렬 나중 만들어진 ver-10이 ver-9보다 먼저 표시
//숫자를 반영한 정렬기능
//파일명 100글자이내, 영문 대소문자, 숫자, 공백, 마침표, 빼기
// 영문자 시작, 숫자 하나이상 포함
//Head: 숫자가 아닌 문자 최소 1글자 이상 -> 사전 순 / 대소문자 구분X
//NUMBEr : 한글자~최대 5글자 앞에 0이 올수 있음 // Head가 같은 경우 -> 숫자 순으로
//TAIL: 그 나머지 부분, 숫자가 다시 나타거나 아무 글자 없음 -> head,number 같은 경우 원래 입력의 주어진 순서 유지
Comparator<String> comp = new Comparator<String>() {
public int compare(String s1,String s2){
//Head는 대소문자 구분이 없으므로
String newHead1 = checkHead(s1).toLowerCase();
String newHead2 = checkHead(s2).toLowerCase();
//Head가 서로 다른경우
if( newHead1.compareTo(newHead2)!=0){
//Head는 사전순으로
return newHead1.compareTo(newHead2); //음수이면 그대로 양수이면 바꾸기
//Head가 같은 경우
} else{
// Number 크기 순으로 배열
return checkNumber(s1) - checkNumber(s2) ;
}
}
};
Arrays.sort(files,comp);
return files;
}
//Head를 분리하는 함수
static String checkHead(String str){
String answer="";
for(char s : str.toCharArray()){
//숫자가 등장하면 즉시 멈추기
if(Character.isDigit(s)) break;
answer+=s;
}
return answer;
}
//Number를 분리하는 함수
static int checkNumber(String str){
//checkHead를 통해서 숫자만 남기기
int length = checkHead(str).length();
str=str.substring(length);
String sub_answer="";
int index=1;
for(char s : str.toCharArray()){
//5글자 넘어가는 경우 break;
if(index>5) break;
//숫자인 경우 누적
if(Character.isDigit(s)) sub_answer+=s;
//영문자가 등장하는 경우 break;
else break;
index++;
}
//숫자로 바꾸기
int answer = Integer.parseInt(sub_answer);
return answer;
}
}