[프로그래머스 - 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를 진행하면서 여러 일정에 신경을 쓰다보니 그간에 코테 준비에 너무 소홀했음을 느꼈다...
  • 문자열을 직접 하나하나 인덱스를 비교하며 자르다보니 시간 효율이 구린 것 같다.