[알고리즘] 3차 파일명 정렬(java)

sonnng·2024년 1월 12일
0

알고리즘

목록 보기
16/17

파일명 정렬 링크

문제풀이

지문에서 요구하는 정렬 기준에 대해 이해하고 Arrays.sort의 new Comparator<>() 내부의 정렬을 잘 다룰 줄 알아야 풀 수 있는 문제다.

  • HEAD는 숫자가 아닌 문자로 이뤄진다. 최소 한 글자 이상이며 문자열 비교시 대소문자 구분은 하지 않는다. '.', '-', ' ' 를 포함한다.
    대소문자 구분x : String.toLowerCase() 또는 String.toUpperCase()
    숫자인가? : Character.isDigit(문자)
    문자인가? : Character.isLetter(문자)
    new Comparator<>()에서 사전순 정렬 :
if(file1.compareTo(file2)>0) return 1;
else if(file1.compareTo(file2) == 0) return 0;
else return -1;
  • NUMBER는 숫자 순으로 정렬한다. 숫자 앞의 0은 무시되며 012 = 12로 처리한다.
    new Comparator<>()에서 숫자순 정렬 : return number1-number2

compareTo 관련

문자열 비교와 숫자의 비교가 가능하다.

  1. 숫자의 비교
    num1.compareTo(num2) : 1, 0, -1 셋 중 하나가 나온다.
    기준(num1)이 비교대상(num2)보다 크면 1, 작으면 -1, 동일하면 0이 나온다.

  2. 문자열 비교
    str.compareTo(str1) : str과 str1의 문자열의 아스키코드 차이값을 리턴한다.
    따라서 new Comparator<>()에서 정렬기준으로 사용하고 싶을때는 if-else 분기방식으로 >0 일때, <0일때, =0일때로 나누어서 처리해야 한다.

만약 대소문자 구분 무시하고 비교하고 싶은 경우 compareToIgnoreCase()를 사용하면 편리하다.

구현코드

import java.util.*;
//소문자로 -> .toLowerCase()
class Solution {
    public String[] solution(String[] files) {
        String[] answer = {};
        
        Arrays.sort(files, (file1, file2) -> {
                file1 = file1.toLowerCase();
                file2 = file2.toLowerCase();
                
                int idx1 = findStringIdx(file1); //문자열이 끝나는 지점 찾기
                int idx2 = findStringIdx(file2);
                String HEADER1 = file1.substring(0, idx1);
                String HEADER2 = file2.substring(0, idx2);

                if(HEADER1.equals(HEADER2)){
                    while(file1.charAt(idx1) == '.' || file1.charAt(idx1) == '-' || file1.charAt(idx1) == ' ' ){
                        idx1++;
                        if(idx1>=file1.length()) return file1.length()-1;
                    }
                    while(file2.charAt(idx2) == '.' || file2.charAt(idx2) == '-' || file2.charAt(idx2) == ' ' ){
                        idx2++;
                        if(idx2>=file2.length()) return file2.length()-1;
                    }
                    
                    int idx3 = findNumber(idx1, file1); //숫자가 끝나는 지점 찾기
                    int idx4 = findNumber(idx2, file2);
                    int NUMBER1 = Integer.parseInt(file1.substring(idx1, idx3));
                    int NUMBER2 = Integer.parseInt(file2.substring(idx2, idx4));
                    return NUMBER1-NUMBER2;
                }
                else if(HEADER1.compareTo(HEADER2)>0){
                    return 1;
                }
                else if(HEADER1.compareTo(HEADER2) == 0){
                    return 0;
                }else{
                    return -1;
                }
            }
        );
        
        
        return files;
    }
    public static int findStringIdx(String file){
        for(int i=0;i<file.length();i++){
            char a = file.charAt(i);
            if(a == '.' || a == ' ' || a == '-') continue;
            else if(!Character.isLetter(a)) return i;
        }
        return file.length();
    }
    public static int findNumber(int idx, String file){
        for(int i=idx;i<file.length();i++){
            char a = file.charAt(i);
             if(a == '.' || a== ' ' || a == '-') return i;
            if(Character.isLetter(a)) return i;
        }
        return file.length();
    }
}

0개의 댓글