[Algorithm] 프로그래머스 파일명 정렬
Updated:
문제 설명
나의 풀이
import Foundation
func solution(_ files:[String]) -> [String] {
var fileList = [File]()
var numberIndex = [Int]()
var charIndex = [Int]()
for file in files {
for (index, char) in file.enumerated() {
if char.isNumber {
numberIndex.append(index)
}
else {
charIndex.append(index)
}
}
let substringIndex1 = file.index(file.startIndex, offsetBy: numberIndex.first!)
if let a = findFirstIndexCompare(charIndex, numberIndex) {
let substringIndex2 = file.index(file.startIndex, offsetBy: a)
let checkIndex2 = file.index(file.startIndex, offsetBy: numberIndex.first! + 5)
// 숫자가 5개 이상인 경우에는 5개까지만 number로 저장
if substringIndex2 > checkIndex2 {
fileList.append(File(head: String(file[file.startIndex..<substringIndex1]),
number: String(file[substringIndex1..<checkIndex2]),
tail: String(file[checkIndex2..<file.endIndex])))
}
else {
fileList.append(File(head: String(file[file.startIndex..<substringIndex1]),
number: String(file[substringIndex1..<substringIndex2]),
tail: String(file[substringIndex2..<file.endIndex])))
}
}
// "F-15"와 같이 tail이 없는 경우
else {
fileList.append(File(head: String(file[file.startIndex..<substringIndex1]),
number: String(file[substringIndex1..<file.endIndex]),
tail: nil))
}
numberIndex = []
charIndex = []
}
let sortedFileList = fileList.sorted { f1, f2 in
if f1.head.lowercased() < f2.head.lowercased() {
return true
}
else if f1.head.lowercased() == f2.head.lowercased() {
if Int(f1.number)! < Int(f2.number)! {
return true
}
}
return false
}
return sortedFileList.map {
if let tail = $0.tail {
return "\($0.head)\($0.number)\(tail)"
}
return "\($0.head)\($0.number)"
}
}
struct File {
var head: String
var number: String
var tail: String?
}
func findFirstIndexCompare(_ cIndex: [Int], _ nIndex: [Int]) -> Int? {
for c in cIndex {
for n in nIndex{
if c > n {
return c
}
}
}
return nil
}
처음에 작성했던 코드는 "F15
“와 같은 파일명을 고려하지 않고 무조건 tail이 존재한다고 가정해서 substring을 진행하여 오류가 났었다. 따라서 이를 해결하기 위해서 optional을 사용해서 문제를 해결하였다.
그러나 이 문제에서 ["img12123001.png", "img12123000.png"]
다음과 같은 예시에서 5글자 까지만 숫자로 인정하므로 실제로 정답은 ["img12123001.png", "img12123000.png"]
이 나와야하지만 그렇지 않고 ["img12123000.png", img12123001.png]
이렇게 나오는 것들이 정답으로 인정되고 있다.. 테스트케이스가 추가되어야할 것 같다.
괜찮은 남의 풀이
import Foundation
extension String{
var numeric: ClosedRange<Character> { return "0"..."9" }
var head: String{
return self.prefix { numeric.contains($0) == false }.uppercased()
}
var number: Int {
return Int( self.drop { numeric.contains($0) == false}
.prefix { numeric.contains($0) == true })!
}
}
func solution(_ files:[String]) -> [String] {
return files.enumerated().sorted { (lhs, rhs) in
let l = lhs.element
let r = rhs.element
if l.head != r.head { return l.head < r.head}
if l.number != r.number { return l.number < r.number}
return lhs.offset < rhs.offset
}.map{ $0.element }
}
좋은 풀이지만 위에서 언급했던 숫자가 5개 이상인 경우에는 잘못된 정답이 출력된다. 그러나 위에서 조건에 따라서 head, number, tail을 추출하는 방법이 매우 흥미롭다.
Leave a comment