[JAVA] 프로그래머스 | 17686 파일명 정렬
📝 TIL
- [프로그래머스] 17696 파일명 정렬
입력 형식
입력으로 배열 files가 주어진다.
files는 1000 개 이하의 파일명을 포함하는 문자열 배열이다.
각 파일명은 100 글자 이하 길이로, 영문 대소문자, 숫자, 공백(" "), 마침표("."), 빼기 부호("-")만으로 이루어져 있다.
파일명은 영문자로 시작하며, 숫자를 하나 이상 포함하고 있다.
중복된 파일명은 없으나, 대소문자나 숫자 앞부분의 0 차이가 있는 경우는 함께 주어질 수 있다. (muzi1.txt, MUZI1.txt, muzi001.txt, muzi1.TXT는 함께 입력으로 주어질 수 있다.)
입출력 예
입력#1
입력: ["img12.png", "img10.png", "img02.png", "img1.png", "IMG01.GIF", "img2.JPG"]
출력#1
출력: ["img1.png", "IMG01.GIF", "img02.png", "img2.JPG", "img10.png", "img12.png"]
🦔 설계 및 시도
처음 생각했을 때
1. 숫자를 기준으로 HEAD / NUMBER / TAIL로 분리하고
2. NUMBER는 숫자로, HEAD는 사전순으로 Lower를 처리해서 정렬하자
라고 생각했고 전반적인 방식은 맞았다!
1, 2번 방식에 만약 HEAD와 NUMBER가 같다면 기존 입력 순서를 유지하는 내용만 추가했으면 됐다.
다만... 구현을 1도 못하는 것이 문제
역시나 문제를 많이 푸는 것이 좀 필요한 거 같다 😭
사실 풀이에 사용된 개념 자체는 거의 다 아는 내용이었는데,
커스텀 객체를 생성하거나 하는 부분을 떠올리지 못했다.
🔥 풀이에 사용된 개념
Character.isDigit(char)
- 숫자인지 판별하는 메서드
커스텀 클래스
구현할 때 헷갈렸던게, HEAD / NUMBER로 나누어 정렬은 해야되나,
반환은 원본 값을 반환해야 했다.
자바에서 정렬 기준을 여러 개가 나눌 때, 객체로 묶어서 관리하는 것이 깔끔하고, 유지보수에 좋다.
따라서 필드를 가진 클래스를 만들어 객체를 관리하
// 커스텀 클래스
class FileInfo {
String head;
int number;
String original;
public FileInfo(String head, int number, String original) {
this.head = head;
this.number = number;
this.original = original;
}
}
💡 풀이 소스 코드
시간복잡도 : O(N*K + N log N)
N : 파일 개수, K : 파일명 평균 길이
파싱 : O(N*K) / 정렬 : N log N
공간복잡도 : O(N*K)
import java.util.*;
// HEAD : 대소문자 구분 X 사전순
// NUMBER : 숫자 오름차순
class Solution {
public String[] solution(String[] files) {
// 1. 파일명 HEAD / NUMBER / TAIL로 자르기
// 커스텀 객체 만들기
List<FileInfo> fileList = new ArrayList<>();
for(String file : files){
fileList.add(parseFile(file));
}
Collections.sort(fileList, (f1, f2) -> {
int headCompare = f1.head.toLowerCase().compareTo(f2.head.toLowerCase());
if (headCompare != 0) return headCompare;
return Integer.compare(f1.number, f2.number);
});
String[] answer = new String[files.length];
for(int i=0; i<fileList.size(); i++) {
answer[i]=fileList.get(i).original;
}
return answer;
}
// 파일명 파싱 메서드
private FileInfo parseFile(String file){
int i=0;
int len=file.length();
// HEAD
StringBuilder head = new StringBuilder();
while (i<len && !Character.isDigit(file.charAt(i))) {
head.append(file.charAt(i));
i++;
}
// NUMBER
StringBuilder number = new StringBuilder();
while (i < len && Character.isDigit(file.charAt(i)) && number.length() < 5) {
number.append(file.charAt(i));
i++;
}
return new FileInfo(head.toString(), Integer.parseInt(number.toString()), file);
}
}
// 커스텀 객체 정의
class FileInfo {
String head;
int number;
String original;
public FileInfo(String head, int number, String original) {
this.head = head;
this.number = number;
this.original = original;
}
}
🚀 새로 배운 내용
- 커스텀 객체를 만드는 연습을 해보자
😺 느낀점
- 단계별로 로직을 나눠 푸는 연습을 하자!
*소스 코드는 다음 깃허브에 올라옵니다 - https://github.com/s0ooo0k/Algorithm_Study
GitHub - s0ooo0k/Algorithm_Study: Algorithm Study 문제 및 풀이
Algorithm Study 문제 및 풀이. Contribute to s0ooo0k/Algorithm_Study development by creating an account on GitHub.
github.com