[프로그래머스] 파일명 정렬 (Java)
https://school.programmers.co.kr/learn/courses/30/lessons/17686?language=java
프로그래머스
SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
문자열, 정렬
아래와 같은 파일명을
"문자열로만 이루어져있는 접두어 부분 = HEAD",
"그 다음 숫자로 이루어진 부분 = NUMBER",
"그 다음 글자 부터 끝까지 = TAIL"
로 구분할 때,
| foo9.txt | foo | 9 | .txt | 
| foo010bar020.zip | foo | 010 | bar020.zip | 
| F-15 | F- | 15 | (빈 문자열) | 
정렬 기준
1. HEAD를 기준으로 알파벳, 길이 순으로 정렬 (Java String CompareTo() 활용)
2. 1기준이 일치할 시, Number를 '숫자'로 취급하여 오름차순 정렬
접근 방법
String List의 sort 함수를 사용했다. 그 안에 람다식에 compare 함수를 구현했는데,
일단 글자마다 순서대로 살피면서 숫자가 등장하기 전까지를 HEAD로 추출
A, B의 HEAD를 CompareTo로 비교해서 사전순으로 정렬되게 했음.
compare함수에서 음수를 반환하면 a,b 순서대로, 양수면 b,a 순서가 된다고 함
그리고 string compareTo는 a.compareTo(b) 이런식으로 쓰면
a < b : 음수
b < a : 양수
라서 오름 차순으로 하고 싶다면, a.compareTo(b)를 반환해야함
그리고 그 다음 순서부터 자른 Number도 Integer.parseInt(str)을 사용해서 정수로 변환하고
오름차순을 원하니까 anum - bnum 하면 b가 클 때 음수 -> 순서 유지 -> 오름차순
소스코드
import java.util.*;
class Solution {
    
    public String[] solution(String[] files) {
        String[] answer = {};
        
        List<String> list = Arrays.asList(files); 
        list.sort((a, b) -> {
            // compare함수의 반환값이 음수면 -> a,b 순서, 양수면 -> b,a 순서
            String ahead = "";
            int anumIdx = 0;
            for(int i = 0 ; i < a.length() ; i++) {
                if(!Character.isDigit(a.charAt(i))) {
                    ahead += a.charAt(i);
                } else {
                    anumIdx = i;
                    break;
                }
            }
                   
            String bhead = "";
            int bnumIdx = 0;
            for(int i = 0 ; i < b.length() ; i++) {
                if(!Character.isDigit(b.charAt(i))) {
                    bhead += b.charAt(i);
                } else {
                    bnumIdx = i; 
                    break;
                }
            }
            
            ahead = ahead.toLowerCase();
            bhead = bhead.toLowerCase();
            
            if (ahead.compareTo(bhead) == 0) { // a > b 면 양수
                // HEAD 순서가 일치 -> number 비교
                String anum = "";
                for(int i = anumIdx; i < a.length() ; i++) {
                    if(Character.isDigit(a.charAt(i))) {
                        anum += a.charAt(i);
                    } else {
                        break;
                    }
                }
                
                String bnum = "";
                for(int i = bnumIdx; i < b.length() ; i++) {
                    if(Character.isDigit(b.charAt(i))) {
                        bnum += b.charAt(i);
                    } else {
                        break;
                    }
                }
                
                Integer aNum = Integer.parseInt(anum);
                Integer bNum = Integer.parseInt(bnum);
                
                return aNum - bNum;
            } else {
                return ahead.compareTo(bhead); // a가 크면 양수 -> 자리 바꿈 -> 오름차순
            }
        });
                
        return list.toArray(new String[list.size()]);
    }
}
중복되는 코드가 많긴 하지만..~