문제

https://programmers.co.kr/learn/courses/30/lessons/17686


코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
public String[] solution(String[] files) {

List<File> fileList = new ArrayList<>();
for (int i = 0; i < files.length; i++) {
char[] array = files[i].toCharArray();

String originName = files[i];
String head = "";
Integer number = 0;

boolean isString = true;
int numberStartIndex = 0;
for (int j = 0; j < array.length; j++) {
if (isString && isNumber(array[j])) {
head = new String(array, 0, j).toUpperCase();
numberStartIndex = j;
isString = false;
continue;
}

if (!isString && !isNumber(array[j])) {
number = Integer.parseInt(new String(array, numberStartIndex, j - numberStartIndex));
isString = true;
break;
}
}

if (!isString) {
number = Integer.parseInt(new String(array, numberStartIndex, array.length - numberStartIndex));
}

fileList.add(new File(originName, head, number, i));
}

sort(fileList);

return fileList.stream()
.map(File::getOriginName)
.toArray(String[]::new);
}

private void sort(List<File> fileList) {
fileList.sort((f1, f2) -> {
if (f1.head.compareTo(f2.head) != 0) {
return f1.head.compareTo(f2.head);
} else if (f1.number.compareTo(f2.number) != 0) {
return f1.number.compareTo(f2.number);
} else {
return f1.index.compareTo(f2.index);
}
});
}

private boolean isNumber(char ch) {
return (48 <= ch && ch <= 57);
}

static class File {
private final String originName;
private final String head;
private final Integer number;
private final Integer index;

public File(String originName, String head, Integer number, Integer index) {
this.originName = originName;
this.head = head;
this.number = number;
this.index = index;
}

public String getOriginName() {
return this.originName;
}

public String getHead() {
return this.head;
}

public Integer getNumber() {
return this.number;
}

public Integer getIndex() {
return this.index;
}
}

흐름

  1. file 개수만큼 반복하면서 파일명을 char array로 만든다.
  2. char array를 숫자가 나올 때 까지 반복한다.
  3. 숫자가 나오면 0부터 숫자가 나온 index까지 짤라서 head 변수에 저장시키고 숫자가 시작된 index와 다음에 숫자인지 체크 할 flag 변수를 false로 변경한다.
  4. head를 만들고 난 후엔 숫자만 뽑아서 number로 저장해야 하므로
  5. 돌면서 현재 문자가 아니고 지금 값도 숫자가 아니면 지금 index까지 잘라서 number에 저장한다.
  6. 만약 tail이 없어서 이번 조건문에 걸리지 않았다면, 숫자가 시직된 index부터 array 길이에서 숫자가 시작된 index를 뺀 크기 만큼 잘라서 number에 저장한다.
  7. 구한 head, number를 가지고 원래 파일명, head, number, 원래 순서를 갖는 File Object를 생성하고 List에 추가한다.
  8. 리스트를 문제의 제약조건 처럼 정렬한다.
    1. head로 비교해서 정렬
    2. head가 같으면 number로 비교해서 정렬
    3. 둘 다 같으면 원래 순서대로 정렬
  9. 정렬한 List를 String[]로 만들어서 return 한다.

결과

번호 속도
테스트 1 통과 (2.80ms, 52.3MB)
테스트 2 통과 (2.92ms, 52.8MB)
테스트 3 통과 (15.41ms, 54.1MB)
테스트 4 통과 (17.89ms, 54.3MB)
테스트 5 통과 (16.74ms, 54.3MB)
테스트 6 통과 (15.07ms, 53.3MB)
테스트 7 통과 (21.21ms, 54.5MB)
테스트 8 통과 (21.20ms, 53.8MB)
테스트 9 통과 (17.57ms, 53.6MB)
테스트 10 통과 (20.00ms, 53.5MB)
테스트 11 통과 (15.30ms, 53.8MB)
테스트 12 통과 (14.44ms, 54.1MB)
테스트 13 통과 (10.24ms, 53.8MB)
테스트 14 통과 (12.50ms, 54.1MB)
테스트 15 통과 (18.61ms, 54.1MB)
테스트 16 통과 (20.40ms, 53.9MB)
테스트 17 통과 (10.36ms, 53.8MB)
테스트 18 통과 (13.84ms, 54.6MB)
테스트 19 통과 (16.07ms, 54.4MB)
테스트 20 통과 (14.91ms, 53.8MB)


정렬을 stream에 추가 할 경우

stream sorted

1
2
3
4
5
6
return fileList.stream()
.sorted(Comparator.comparing(File::getHead)
.thenComparing(Comparator.comparing(File::getNumber)
.thenComparing(File::getIndex)))
.map(File::getOriginName)
.toArray(String[]::new);

결과

번호 속도
테스트 1 통과 (10.64ms, 53.2MB)
테스트 2 통과 (18.65ms, 53.2MB)
테스트 3 통과 (25.96ms, 54.7MB)
테스트 4 통과 (24.73ms, 54.8MB)
테스트 5 통과 (20.97ms, 54.3MB)
테스트 6 통과 (29.57ms, 54.3MB)
테스트 7 통과 (30.45ms, 54.3MB)
테스트 8 통과 (24.91ms, 54.3MB)
테스트 9 통과 (26.40ms, 54.8MB)
테스트 10 통과 (28.88ms, 54.1MB)
테스트 11 통과 (22.73ms, 54.7MB)
테스트 12 통과 (25.60ms, 54.4MB)
테스트 13 통과 (22.06ms, 54.2MB)
테스트 14 통과 (19.49ms, 54.9MB)
테스트 15 통과 (17.53ms, 54.2MB)
테스트 16 통과 (20.05ms, 54.1MB)
테스트 17 통과 (18.01ms, 54.7MB)
테스트 18 통과 (18.53ms, 53.7MB)
테스트 19 통과 (26.25ms, 54.2MB)
테스트 20 통과 (20.81ms, 55.2MB)

테스트 케이스

1
2
3
4
5
assertArrayEquals(new String[] {"img1.png", "IMG01.GIF", "img02.png", "img2.JPG", "img10.png", "img12.png"}, test.solution(new String[] {"img12.png", "img10.png", "img02.png", "img1.png", "IMG01.GIF", "img2.JPG"}));
assertArrayEquals(new String[] {"A-10 Thunderbolt II", "B-50 Superfortress", "F-5 Freedom Fighter", "F-14 Tomcat"}, test.solution(new String[] {"F-5 Freedom Fighter", "B-50 Superfortress", "A-10 Thunderbolt II", "F-14 Tomcat"}));
assertArrayEquals(new String[] {"img100.p2ng", "img202.png123"}, test.solution(new String[] {"img202.png123", "img100.p2ng"}));
assertArrayEquals(new String[] {"foo010bar020.zip", "foo010bar030.zip"}, test.solution(new String[] {"foo010bar020.zip", "foo010bar030.zip"}));
assertArrayEquals(new String[] {"F-15", "F-17", "F-22"}, test.solution(new String[] {"F-22", "F-17", "F-15"}));