https://school.programmers.co.kr/learn/courses/30/lessons/17686
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
파일은 HEAD, NUMBER, TAIL 부분으로 나눌 수 있다.
파일명 | HEAD | NUMBER | TAIL |
foo9.txt | foo | 9 | .txt |
foo010bar020.zip | foo | 010 | bar020.zip |
F-15 | F- | 15 | (빈 문자열) |
HEAD는 숫자가 아닌 문자로 이루어져 있으며, 최소한 한 글자 이상이다.
NUMBER는 한 글자에서 최대 다섯 글자 사이의 연속된 숫자로 이루어져 있으며, 앞쪽에 0이 올 수 있다.
0부터 99999 사이의 숫자로, 00000이나 0101 등도 가능하다.
TAIL은 그 나머지 부분으로, 여기에는 숫자가 다시 나타날 수도 있으며, 아무 글자도 없을 수 있다.
파일명은 우선 HEAD 부분을 기준으로 사전 순으로 정렬한다.
이때, 문자열 비교 시 대소문자 구분을 하지 않는다. MUZI와 muzi, MuZi는 정렬 시에 같은 순서로 취급된다.
파일명의 HEAD 부분이 대소문자 차이 외에는 같을 경우, NUMBER의 숫자 순으로 정렬한다.
9 < 10 < 0011 < 012 < 13 < 014 순으로 정렬된다.
숫자 앞의 0은 무시되며, 012와 12는 정렬 시에 같은 같은 값으로 처리된다.
두 파일의 HEAD 부분과, NUMBER의 숫자도 같을 경우, 원래 입력에 주어진 순서를 유지한다.
MUZI01.zip과 muzi1.png가 입력으로 들어오면, 정렬 후에도 입력 시 주어진 두 파일의 순서가 바뀌어서는 안 된다.
조건에 맞게 정렬하기 위해 다음과 같이 코드를 작성했다.
먼저 HEAD, NUMBER, TAIL 부분으로 자르기 위한 메서드를 준비했다.
대소문자 구분을 하지 않기 때문에 .toLowerCase()를 이용하여 소문자로 만들어 준 다음
"a-z", "-", " ", "."인 경우 HEAD에 추가되도록 하였고, 그다음 인덱스가 문자 길이의 끝인 경우 종료, 숫자로 된 경우 NUMBER에 추가되기 시작하도록 하였다.
NUMBER는 길이가 5가 넘어가지 않도록 numberCnt를 따로 두어서 길이가 5가 넘어가게 된다면 TAIL에 저장되도록 하였다.
public String[] process(String file) {
String[] fileInfo = new String[3];
StringBuilder HEAD = new StringBuilder();
StringBuilder NUMBER = new StringBuilder();
StringBuilder TAIL = new StringBuilder();
String word = file.toLowerCase();
int index = 0;
int process = 0;
int numberCnt = 0;
while (index != file.length()) {
if (process == 0 && ((word.charAt(index) >= 'a' && word.charAt(index) <= 'z')
|| word.charAt(index) == '-' || word.charAt(index) ==' '
|| word.charAt(index) == '.')) {
HEAD.append(word.charAt(index));
index++;
if (index == file.length()) break;
if (word.charAt(index) >= '0' && word.charAt(index) <= '9') process = 1;
} else if (numberCnt < 5 && process == 1 && (word.charAt(index) >= '0'
&& word.charAt(index) <= '9')) {
NUMBER.append(word.charAt(index));
index++;
numberCnt++;
if (index == file.length()) break;
if (word.charAt(index) >= '0' && word.charAt(index) <= '9') continue;
else process = 2;
} else {
TAIL.append(word.charAt(index));
index++;
}
}
fileInfo[0] = HEAD.toString();
fileInfo[1] = NUMBER.toString();
fileInfo[2] = TAIL.toString();
return fileInfo;
}
이후 이것을 기반으로 조건 o1, o2를 HEAD, NUMBER, TAIL로 된 배열로 만들고
HEAD를 비교하여 정렬, 만약 HEAD 조건이 같다면 NUMBER를 int형으로 구분하여 조건에 맞게 정렬하였다.
Arrays.sort(files, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
String[] o1Info = process(o1);
String[] o2Info = process(o2);
if (o1Info[0].compareTo(o2Info[0]) < 0) return -1;
else if (o1Info[0].compareTo(o2Info[0]) == 0) {
return Integer.parseInt(o1Info[1]) - Integer.parseInt(o2Info[1]);
}
else if (o1Info[0].compareTo(o2Info[0]) > 0) return 1;
else return 0;
}
});
그런데 TAIL은 조건과 아무런 관련이 없다. 그래서 process()에서 TAIL과 관련된 부분은 없어도 될 것이다.
아래는 전체 코드이다. 여기서 TAIL과 관련된 부분을 수정하고 TAIL을 처리하는 부분에서 break를 해도 될 것이다.
import java.util.Arrays;
import java.util.Comparator;
class Solution {
public String[] solution(String[] files) {
Arrays.sort(files, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
String[] o1Info = process(o1);
String[] o2Info = process(o2);
if (o1Info[0].compareTo(o2Info[0]) < 0) return -1;
else if (o1Info[0].compareTo(o2Info[0]) == 0) {
return Integer.parseInt(o1Info[1]) - Integer.parseInt(o2Info[1]);
}
else if (o1Info[0].compareTo(o2Info[0]) > 0) return 1;
else return 0;
}
});
return files;
}
public String[] process(String file) {
String[] fileInfo = new String[3];
StringBuilder HEAD = new StringBuilder();
StringBuilder NUMBER = new StringBuilder();
StringBuilder TAIL = new StringBuilder();
String word = file.toLowerCase();
int index = 0;
int process = 0;
int numberCnt = 0;
while (index != file.length()) {
if (process == 0 && ((word.charAt(index) >= 'a' && word.charAt(index) <= 'z')
|| word.charAt(index) == '-' || word.charAt(index) ==' '
|| word.charAt(index) == '.')) {
HEAD.append(word.charAt(index));
index++;
if (index == file.length()) break;
if (word.charAt(index) >= '0' && word.charAt(index) <= '9') process = 1;
} else if (numberCnt < 5 && process == 1 && (word.charAt(index) >= '0'
&& word.charAt(index) <= '9')) {
NUMBER.append(word.charAt(index));
index++;
numberCnt++;
if (index == file.length()) break;
if (word.charAt(index) >= '0' && word.charAt(index) <= '9') continue;
else process = 2;
} else {
TAIL.append(word.charAt(index));
index++;
}
}
fileInfo[0] = HEAD.toString();
fileInfo[1] = NUMBER.toString();
fileInfo[2] = TAIL.toString();
return fileInfo;
}
}
'Programmers' 카테고리의 다른 글
[프로그래머스][JAVA]Lv. 2 - 전화번호 목록 (0) | 2023.05.02 |
---|---|
[프로그래머스][JAVA]Lv. 2 - n진수 게임 (1) | 2023.04.27 |
[프로그래머스][JAVA]Lv. 1 - 달리기 경주 (0) | 2023.04.13 |
[프로그래머스][JAVA]Lv. 2 - 압축 (0) | 2023.04.11 |
[프로그래머스][JAVA]Lv. 2 - 연속된 부분 수열의 합 (0) | 2023.04.08 |