파일명 정렬
내 풀이
- String은 compareTo를 사용해서 정렬한다.
- List<String>을 String[]으로 변환할 때 toArray(String[]::new)를 사용한다.
- s1 문자열의 경우 숫자가 나온 경우 length를 넘어서서 numRanges[1]이 0인채 for loop이 끝나게 되는데 이를 처리해주기 위해 분기가 하나 더 필요했다.
import java.util.*;
class Solution {
public String[] solution(String[] files) {
String[] ans = Arrays.stream(files)
.sorted(new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
int[] numRanges = new int[4];
int max = Collections.max(List.of(s1.length(), s2.length()));
for (int i = 0; i < max; i++) {
if(s1.length() > i) {
if (s1.length() > i && numRanges[0] == 0 && Character.isDigit(s1.charAt(i))) {
numRanges[0] = i;
} else if (s1.length() > i && numRanges[0] != 0 && numRanges[1] == 0) {
if (!Character.isDigit(s1.charAt(i))) {
numRanges[1] = i;
} else if (s1.length() - 1 == i || numRanges[0] + 4 == i) {
numRanges[1] = i + 1;
}
}
}
if(s2.length() > i) {
if (s2.length() > i && numRanges[2] == 0 && Character.isDigit(s2.charAt(i))) {
numRanges[2] = i;
} else if (s2.length() > i && numRanges[2] != 0 && numRanges[3] == 0) {
if (!Character.isDigit(s2.charAt(i))) {
numRanges[3] = i;
} else if (s2.length() - 1 == i || numRanges[2] + 4 == i) {
numRanges[3] = i + 1;
}
}
}
if (numRanges[0] != 0 && numRanges[1] != 0 && numRanges[2] != 0 && numRanges[3] != 0) {
break;
}
}
if(numRanges[1] == 0) {
numRanges[1] = s1.length();
}
if(numRanges[3] == 0) {
numRanges[3] = s2.length();
}
String HEAD1 = s1.substring(0, numRanges[0]);
int NUM1 = Integer.parseInt(s1.substring(numRanges[0], numRanges[1]));
String HEAD2 = s2.substring(0, numRanges[2]);
int NUM2 = Integer.parseInt(s2.substring(numRanges[2], numRanges[3]));
Integer headCompareResult = HEAD1.toUpperCase().compareTo(HEAD2.toUpperCase());
if (headCompareResult != 0) {
return headCompareResult;
} else if (headCompareResult == 0) {
return Integer.compare(NUM1, NUM2);
}
return 0;
}
})
.toArray(String[]::new);
return ans;
}
}
개선된 풀이
import java.util.*;
class Solution {
public String[] solution(String[] files) {
return Arrays.stream(files)
.sorted((s1, s2) -> {
String[] parsed1 = parseFileName(s1);
String[] parsed2 = parseFileName(s2);
int headCompare = parsed1[0].compareToIgnoreCase(parsed2[0]);
if (headCompare != 0) return headCompare;
return Integer.compare(Integer.parseInt(parsed1[1]), Integer.parseInt(parsed2[1]));
})
.toArray(String[]::new);
}
private String[] parseFileName(String file) {
int firstDigit = -1;
int length = file.length();
for (int i = 0; i < length; i++) {
if (Character.isDigit(file.charAt(i))) {
firstDigit = i;
break;
}
}
int lastDigit = firstDigit;
while (lastDigit < length && Character.isDigit(file.charAt(lastDigit)) && lastDigit - firstDigit < 5) {
lastDigit++;
}
String head = file.substring(0, firstDigit);
String number = file.substring(firstDigit, lastDigit);
return new String[]{head, number};
}
}