프로그래머스 LV2. [3차] 파일명 정렬
✅ 프로그래머스 LV2. [3차] 파일명 정렬
하하,, 문제 딱 봤을 때 이건 10분컷! 이랬는데 결국은 엄청 오래걸림
처음에는 정규 표현식으로 해결하려고 했는데, 정규 표현식 공부를 제대로 해본 적 없어서 구글링으로 사용하는건 학습에 별로 도움 안될거 같아서 패스 (+ 정규 표현식의 시간복잡도에 대한 개념이 없어서 알고리즘이 효율적이지 않을 수도 있단 생각도 들었음)
그래서 그냥 for문을 통해서 접근함. 근데!! 65점에서 막혔음 ^__^
✅ 코드 (틀린코드 65점)
하도 많이 틀려서 질문도 함.. 반례를 못찾아서
https://programmers.co.kr/questions/30185
테스트케이스 3, 4, 5, 6, 7, 19, 20번이 틀림
질문 예시도 보는데 보통 3번은 다 맞던데 나만 틀려서 하,, 한숨 푸욱 ,,
import Foundation
func solution(_ files:[String]) -> [String] {
// head, number는 무조건 1글자 이상이나 tail은 없을 수도 있다.
var fileList = [(String, String, String)]()
// 데이터 정제
files.forEach { file in
var numberFlag = false
var numberRangeStart = -1
var numberCount = 0 // 숫자는 최대 5개이므로
for i in 0..<file.count {
let idx = file.index(file.startIndex, offsetBy: i)
if file[idx].isNumber && numberCount != 0 && file[idx] == "0" {
print(numberCount)
numberCount += 1
}
if file[idx].isNumber && numberFlag == false {
numberFlag = true
numberRangeStart = i
numberCount = 1
} else if (!file[idx].isNumber && numberFlag == true) || numberCount >= 5 {
// 이때 number의 range가 정해진다.
let headIndex = file.index(file.startIndex, offsetBy: numberRangeStart)
let head = String(file[..<headIndex])
let number = String(file[headIndex..<idx])
let tail = String(file[idx...])
let data = (head, number, tail)
fileList.append(data)
numberFlag = false
break
}
}
if numberFlag == true { // 여전히 true인 경우는 파일의 tail이 숫자인경우
let headIndex = file.index(file.startIndex, offsetBy: numberRangeStart)
let head = String(file[..<headIndex])
let number = String(file[headIndex...])
let data = (head, number, "")
fileList.append(data)
}
}
// 데이터 정렬
// head -> number -> tail의 우선순위
let sortedList = fileList.sorted {
if $0.0.lowercased() == $1.0.lowercased() {
return Int($0.1)! < Int($1.1)!
}
return $0.0 < $1.0
}
// 출력부
var answer = [String]()
sortedList.forEach { file in
answer.append("\(file.0)\(file.1)\(file.2)")
}
return answer
}
✅ 맞은코드
카카오 해설도 찾아보고 뭐 진짜 자료를 많이 서칭해봄.
정렬이 stable하지 않은지 찾아보니까 swift 5부터는 정렬이 stable하게 바뀐것 같고 왜 안되는지 .. ㅠㅠ
아무리 생각해도 로직은 맞는거 같아서 스스로 반례가 될 수 있는 케이스들을 만들어봄.근데 결국은.. 정렬 부분의 문제였는데, sortedList쪽에 lowerCased()를 전부 붙여주어야 했다.
func solution(_ files:[String]) -> [String] {
// head, number는 무조건 1글자 이상이나 tail은 없을 수도 있다.
var fileList = [(String, String, String)]()
// 데이터 정제
files.forEach { file in
var numberFlag = false
var numberRangeStart = -1
var numberCount = 0 // 숫자는 최대 5개이므로
for i in 0..<file.count {
let idx = file.index(file.startIndex, offsetBy: i)
if file[idx].isNumber && numberCount != 0 && file[idx] == "0" {
print(numberCount)
numberCount += 1
}
if file[idx].isNumber && numberFlag == false {
numberFlag = true
numberRangeStart = i
numberCount = 1
} else if (!file[idx].isNumber && numberFlag == true) || numberCount >= 5 {
// 이때 number의 range가 정해진다.
let headIndex = file.index(file.startIndex, offsetBy: numberRangeStart)
let head = String(file[..<headIndex])
let number = String(file[headIndex..<idx])
let tail = String(file[idx...])
let data = (head, number, tail)
fileList.append(data)
numberFlag = false
break
}
}
if numberFlag == true { // 여전히 true인 경우는 파일의 tail이 숫자인경우
let headIndex = file.index(file.startIndex, offsetBy: numberRangeStart)
let head = String(file[..<headIndex])
let number = String(file[headIndex...])
let data = (head, number, "")
fileList.append(data)
}
}
// 데이터 정렬
// head -> number -> tail의 우선순위
let sortedList = fileList.sorted {
if $0.0.lowercased() == $1.0.lowercased() {
return Int($0.1)! < Int($1.1)!
}
return $0.0.lowercased() < $1.0.lowercased() // 여기가 문제였음 !!
}
// 출력부
var answer = [String]()
sortedList.forEach { file in
answer.append("\(file.0)\(file.1)\(file.2)")
}
return answer
}
'알고리즘 문제 풀이' 카테고리의 다른 글
[Swift] 프로그래머스 LV2. [1차] 뉴스 클러스터링 (0) | 2022.04.26 |
---|---|
[Swift] 프로그래머스 LV2. 수식 최대화 (0) | 2022.04.16 |
[Swift] 프로그래머스 LV2. 방문 길이 (0) | 2022.04.16 |
[Swift] 프로그래머스 LV2. 주차 요금 계산 (0) | 2022.04.16 |
[Swift] 프로그래머스 LV2. 큰 수 만들기 (4) | 2022.04.13 |