Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Algorithm] 파일명 정렬 #111

Closed
hwangJi-dev opened this issue Feb 16, 2023 · 0 comments
Closed

[Algorithm] 파일명 정렬 #111

hwangJi-dev opened this issue Feb 16, 2023 · 0 comments

Comments

@hwangJi-dev
Copy link
Owner

hwangJi-dev commented Feb 16, 2023

💬 문제

파일명 정렬


💬 Idea

  • HEAD와 NUMBER를 구분해주기

    • HEAD : 숫자가 아닌 첫 부분을 반환. 이 때 HEAD 부분의 대소문자는 정렬 시 구분이 되지 않아도 되므로 lowercased()를 적용해준다.
    • NUMBER : 숫자가 아닌 부분을 건너띄고 숫자부터 ~ 다시 문자가 나오는 부분까지를 반환
    • TAIL: 나머지 // 이 부분은 문제 풀이에 큰 상관이 없기에 따로 구하지 않아도 된다.
  • HEAD값을 key값으로 하여 Dictionary에 (NUMBER, ORIGINALFILE, index) 를 값으로 저장해준다. // 숫자, 기존 파일명, 들어온 순서

  • 정렬하기

    • HEAD값이 같은 파일명이 존재할 때 → values에 여러 값이 저장되기 때문에 딕셔너리를 key값으로 우선 정렬한 후 value 값을 돌며 조건대로 숫자순, 들어온 순 정렬을 하는 로직

💬 풀이

func solution(_ files:[String]) -> [String] {
    var headNumberDict: [String: [(Int, String, Int)]] = [:] 
    var res: [String] = []
    
    for (index, file) in files.enumerated() {
        let HEAD = file.prefix{ !$0.isNumber }.lowercased()
        let NUMBER = file.drop { !$0.isNumber }.prefix(while: { $0.isNumber })
        
        if headNumberDict[HEAD] != nil {
            headNumberDict[HEAD]?.append((Int(NUMBER) ?? 0, file, index))
        } else {
            headNumberDict[HEAD] = [(Int(NUMBER) ?? 0, file, index)]
        }
    }
    
    for i in headNumberDict.sorted(by: { $0.key < $1.key }) {
        let s = i.value.sorted(by: { $0.0 == $1.0 ? $0.2 < $1.2 : $0.0 < $1.0 })
        for j in s {
            res.append(j.1)
        }
    }

    return res
}

💬 더 나은 방법?

  • 딕셔너리를 사용하고도 sorted(by: )를 사용할 것이면
  • 딕셔너리를 사용하지 않고 배열을 사용하여 한번에 sorted(by: ) 에서 조건을 주어 사용자 지정 정렬을 해줄 수 있다.
    → 2중 for문을 사용하지 않아도 되어 코드도 효율적이고 훨씬 깔끔하다.
func solution(files:[String]) -> [String] {
    var arr: [(String, Int, Int, String)] = []
    var res: [String] = []
    
    for (index, file) in files.enumerated() {
        let HEAD = file.prefix{ !$0.isNumber }.lowercased()
        let NUMBER = file.drop{ !$0.isNumber }.prefix(while: { $0.isNumber }).prefix(5)
        
        arr.append((HEAD, Int(NUMBER) ?? 0, index, file))
    }
    
    arr = arr.sorted(by: {
        if $0.0 != $1.0 { return $0.0 < $1.0 }
        if $0.1 != $1.1 { return $0.1 < $1.1 }
        return $0.2 < $1.2
    })
    
    for i in arr {
        res.append(i.3)
    }

    return res
}

💬 알게된 문법

✅ drop(while:)

주어진 조건자를 건너띈 첫번째 시퀀스부터 반환합니다.

let numbers = [3, 7, 4, -2, 9, -6, 10, 1]
let startingWithNegative = numbers.drop(while: { $0 > 0 })
// startingWithNegative == [-2, 9, -6, 10, 1]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant