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 |