[프로그래머스 - 2] [3차] 파일명 정렬
2021. 12. 17. 12:52ㆍ프로그래머스



접근법
- String 배열이 주어지고 그 안의 파일명을 문자 / 숫자 / 나머지로 구분하여 정렬하는 문제라고 생각했다.
- Character의 isDigit을 활용해서 숫자가 나올 때까지를 잘라서 Head라고 구분하고 return배열의 0번째 인덱스에 저장했다.
- 그 후 index부터 Digit이 안나올 때까지를 다시 탐색해서 숫자로 구분하고 0을 제거하기 위해 Integer형으로 변경해서 1번째 인덱스에 저장했다.
- 그 뒤는 숫자, 문자와 상관없이 TAIL로 구분하여 2번째 인덱스에 저장한 후 해당 String 배열을 반환한다.
- Digit이 끝까지 나오는경우(ex, F-51) return값이 달라지므로 for문 밖에서 returnStr[1], returnStr[2]를 따로 지정한 후 반환해줬다.
- 다시 Solution 함수로 돌아와서 Arrays의 sort 라이브러리를 활용하여 정렬을 해준다. 이 때 comperator를 재정의해서 사용하였다.
- 가장 먼저 비교할 String o1, o2를 내가 만든 함수 cutting을 사용하여 HEAD / NUMBER / TAIL 형식에 맞는 배열로 변환한다.
- HEAD값이 다른 경우 두 HEAD를 비교해서 return을 하고, 그 외의 경우에는 NUMBER를 Integer형식으로 변환한 후 비교하여 반환을 했다. (TAIL은 굳이 비교를 할 필요가 없음)
풀이
package Level2;
import java.util.Arrays;
import java.util.Comparator;
public class SortByFileName {
public static void main(String[] args) {
System.out.println(Arrays.toString(solution(new String[] {"img12.png", "img10.png", "img02.png", "img1.png", "IMG01.GIF", "img2.JPG"})));
System.out.println(Arrays.toString(solution(new String[] {"F-5 Freedom Fighter", "B-50 Superfortress", "A-10 Thunderbolt II", "F-14 Tomcat"})));
System.out.println(Arrays.toString(solution(new String[] {"F-5", "B-50", "A-10", "F-14"})));
}
public static String[] solution(String[] files) {
Arrays.sort(files, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
// 문자열을 형식에 맞는 문자열 배열로 치환
String[] str1 = cutting(o1);
String[] str2 = cutting(o2);
if(str1[0].equals(str2[0])) { // HEAD가 같은 경우
// NUMBER의 Integer값을 비교하여 return
return Integer.compare(Integer.parseInt(str1[1]), Integer.parseInt(str2[1]));
} else { // HEAD가 다른 경우
return str1[0].compareTo(str2[0]);
}
}
});
return files;
}
public static String[] cutting(String str) {
String[] returnStr = new String[3];
boolean flag = true; // HEAD, NUMBER를 구분하기 위해 사용 | digit이 시작되면 false로 바뀜
int index = 0; // 문자열이 끝나는 지점을 가르킬 인덱스
for(int i = 0; i < str.length(); i++) {
if(flag && Character.isDigit(str.charAt(i))) { // HEAD가 끝나는 지점, 즉 digit이 시작되는 지점을 찾는다.
returnStr[0] = str.substring(0, i).toLowerCase(); // 대소문자 구분이 없으므로 소문자로 치환
index = i;
flag = false;
}
if(!flag && !Character.isDigit(str.charAt(i))) { // digit이 끝나는 지점
returnStr[1] = String.valueOf(Integer.parseInt(str.substring(index, i)));
returnStr[2] = str.substring(i).toLowerCase();
return returnStr;
}
}
// 숫자로 끝나는 경우 returnStr의 1번째와 2번째 비어있으므로 직접 채워준다.
returnStr[1] = String.valueOf(Integer.parseInt(str.substring(index)));
returnStr[2] = "";
return returnStr;
}
}
결과

느낀점
- SSAFY를 진행하면서 여러 일정에 신경을 쓰다보니 그간에 코테 준비에 너무 소홀했음을 느꼈다...
- 문자열을 직접 하나하나 인덱스를 비교하며 자르다보니 시간 효율이 구린 것 같다.