728x90
반응형
https://programmers.co.kr/learn/courses/30/lessons/17686?language=swift#
파일명을 head, number, index 우선순위로 정렬해야하는 문제.
핵심 규칙은 다음과 같다.
- 파일명은 우선 HEAD 부분을 기준으로 사전 순으로 정렬한다. 이때, 문자열 비교 시 대소문자 구분을 하지 않는다. MUZI와 muzi, MuZi는 정렬 시에 같은 순서로 취급된다.
- 파일명의 HEAD 부분이 대소문자 차이 외에는 같을 경우, NUMBER의 숫자 순으로 정렬한다. 9 < 10 < 0011 < 012 < 13 < 014 순으로 정렬된다. 숫자 앞의 0은 무시되며, 012와 12는 정렬 시에 같은 같은 값으로 처리된다.
- 두 파일의 HEAD 부분과, NUMBER의 숫자도 같을 경우, 원래 입력에 주어진 순서를 유지한다. MUZI01.zip과 muzi1.png가 입력으로 들어오면, 정렬 후에도 입력 시 주어진 두 파일의 순서가 바뀌어서는 안 된다.
구현이 필요한 것은 다음과 같다.
- head와 number 분리
- head 소문자 통일
- (head, number, index)를 한 쌍으로 조건에 맞는 정렬
func solution(_ files:[String]) -> [String] {
// (head, number, index) 순서로 저장
var fileOrder = [(String, String, Int)]()
// index 저장을 위해 enumerated
for (i,file) in files.enumerated() {
// head와 number 저장
let head = headAndNumber(file).0.lowercased()
let number = headAndNumber(file).1
fileOrder.append((head, number, i))
}
// 정렬
let fileOrderSorted = fileOrder.sorted {
// head가 다를 때
if $0.0 != $1.0 {
// head 기준 정렬
return $0.0 < $1.0
// head가 같을 때
} else {
let numleft = Int($0.1)!
let numright = Int($1.1)!
// number가 같을 때
if numleft == numright {
// index 순서로 정렬
return $0.2 < $1.2
// number가 다를 때
} else {
return numleft < numright
}
}
// index만 골라서 indexing
}.map { files[$0.2] }
return fileOrderSorted
}
func headAndNumber(_ str: String) -> (String, String) {
var str2 = str.map {String($0)}
let spe = [".","-"," "]
var head = ""
var number = ""
var idx = 0
// 앞에서부터 문자+특수문자만
for s in str2 {
if Character(s).isLetter || spe.contains(s) {
head.append(s)
idx += 1
} else {
break
}
}
// 앞에서부터 숫자만 가져오기 위함
for s in str2[idx...] {
if Character(s).isNumber {
number.append(s)
} else {
break
}
}
return (head,number)
}
head와 number를 분리하는데 정규표현식을 쓰지 않고 조금 비효율적인 코드를 짠 것 같다...
이건 추후 수정이 필요해보인다.
그리고 정렬을 구현하는 분에서 후행 클로저에 조건을 추가하는 것에 대해서는 조금 더 익숙해질 필요가 있을 것 같다.
끄읕
728x90
반응형