문제 이름은 파일명 정렬이지만 정렬보다 문자열을 분리하는데 더 고민을 많이 했던 것 같다.
요구 조건도 간단하게 처리할 수 있는 정도여서 어려운 문제는 아니었던 것 같다.
로직은 문자열을 head - number -tail 부분으로 분리해서 File 인스턴스를 생성해 리스트에 넣고 정렬하면 된다.
문자열 분리는 처음에 split으로 시도했으나 regex를 [0-9]으로 설정하면 기준 문자가 포함되지 않아서 실패했고
StringTokenizer를 사용하면 기준 문자는 포함할 수 있지만 delim을 1~99999까지 만들 수가 없어서 실패했다.
어쩔 수 없이 number 부분이 시작되는 인덱스와 끝나는 인덱스를 찾아 subString으로 나누어서 처리했다.
이 부분의 로직이 if문이 중첩되어 있는 부분인데 너무 길고 눈에 잘 들어오지 않기 때문에 리펙터링이 필요할 것 같다.
문제에 tail 부분이 없을수도 있다고 했으므로 문자열 분리가 끝났는데도 end가 0이면 tail이 없다는 의미임으로 length() - 1 값을 넣어주었다.
문자열 분리가 끝났으면 List <File>에 인스턴스를 생성해 삽입하고 Comparator를 이용해 정렬한다.
여기서 생각해야 할 문제의 요구 조건은
1. head 부분에서 대소문자를 구별하지 않는다고 했으므로 문자열을 toLowerCase()를 이용해서 반환한다.
2. 9 < 10 < 0011 < 012 < 13 < 014 순으로 처럼 앞자리의 0은 무시된다고 했으므로 parseInt를 이용해서 반환하면 자연스럽게 앞자리의 0은 사라진다.
그렇게 정렬이 끝나면 File 클래스의 getStr을 이용해서 answer 배열에 삽입하면 된다.
최종 코드
import java.util.*;
class Solution {
public String[] solution(String[] files) {
String[] answer = new String[files.length];
// File 객체를 담을 list 생성
List<File> list = new ArrayList<>();
// subString으로 문자열 나누기
for (int i = 0; i < files.length; i++) {
String temp = files[i];
// number 부분이 시작되었는지 판단하는 변수
boolean flag = false;
// number 부분의 시작과 끝 인덱스 변수, number 부분의 길이 변수
int start = 0;
int end = 0;
int cnt = 0;
for (int j = 0; j < temp.length(); j++) {
// number 문자가 나오지 않았다는것
if(!flag) {
if(Character.isDigit(temp.charAt(j))) {
flag = true;
start = j;
cnt++;
}
// number 문자가 시작 되었으면
} else {
if(cnt != 5) {
// 숫자라면
if(Character.isDigit(temp.charAt(j))) {
cnt++;
// number 부분이 끝났다는 것
} else {
end = j - 1;
break;
}
} else {
end = j - 1;
break;
}
}
}
// end가 0이면 tail이 없다는 의미
if(end == 0) {
end = temp.length() - 1;
}
// FIle 리스트에 값 삽입
list.add(new File(temp.substring(0, start), temp.substring(start, end + 1), temp.substring(end + 1) ,""));
}
// 1순위 - head값을 오름차순, 2순위 number의 값을 오름차순으로 정렬
list.sort(Comparator.comparing(File::getHead).thenComparing(File::getNumber));
// list에서 str을 answer 배열에 삽입
for (int i = 0; i < list.size(); i++) {
answer[i] = list.get(i).getStr();
}
return answer;
}
// File 클래스
static class File {
String head;
String number;
String tail;
String str;
// 생성자
File(String head, String number, String tail, String str) {
this.head = head;
this.number = number;
this.tail = tail;
this.str = str;
}
// String을 만들어 반환하는 메서드
public String getStr() {
str = head + number + tail;
return str;
}
// head를 소문자로 바꾸어 반환하는 메서드
public String getHead() {
return head.toLowerCase();
}
// number를 Integer로 바꾸어 반환하는 메서드
public int getNumber() {
return Integer.parseInt(number);
}
}
}
'코딩 테스트' 카테고리의 다른 글
(Java) 프로그래머스 - 삼각 달팽이 (0) | 2022.09.07 |
---|---|
(Java) 프로그래머스 - 2개 이하로 다른 비트 (0) | 2022.09.06 |
(Java) 코드 스쿼드 - 숫자 야구 게임 (0) | 2022.09.03 |
(Java) 프로그래머스 - 프렌즈4블록 (0) | 2022.09.01 |
(Java) 프로그래머스 - 두 큐 합 같게 만들기 (0) | 2022.09.01 |