본문 바로가기
Xcode/Swift - Algorithm

Swift ) 프로그래머스(Lv2) - [3차] 압축 (Hash)

by 후르륵짭짭 2020. 9. 10.
728x90
반응형

programmers.co.kr/learn/courses/30/lessons/17684

 

코딩테스트 연습 - [3차] 압축

TOBEORNOTTOBEORTOBEORNOT [20, 15, 2, 5, 15, 18, 14, 15, 20, 27, 29, 31, 36, 30, 32, 34]

programmers.co.kr

안녕하세요 후르륵짭짭입니다.

이 문제는 그냥 전형적인 Hash 문제 입니다.

자료구조를 알고 있느냐 모르냐를 물어본 것 같아요.

 

** 저의 풀이 **

//39:07
func solution(_ msg:String) -> [Int] {
    
    var dict : [String : Int] = [:]
    
    for start in 0..<26{
        
        let word = String( UnicodeScalar(65 + start)! )
        
        dict[word] = start + 1
    }
    
    let msgList = Array(msg).map { (char) -> String in
        return String(char)
    }
    
    var answer : [Int] = []
    var index = 0
    
    while index < msgList.count{
        
        var searchString = ""
        var inputString = ""
        var cnt = 0
        
        for temp in index..<msgList.count {
            
            inputString += msgList[temp]

            if dict[inputString] == nil{
                
//                print(inputString, searchString)
                dict[inputString] = dict.count + 1
                
                //출력
                answer.append(dict[searchString]!)
                
                break
            }
            
            searchString += msgList[temp]
            cnt += 1
            
            //마지막 위치
            if temp == msgList.count - 1{
                answer.append(dict[searchString]!)
            }
            
        }
        
        index += cnt
//        print(index , msgList.count)
        
    }
    
//    print(answer)
    
    return answer
}

 

저는 그냥 UnicodeScalar 를 통해서 아스키 코드 값을 문자로 변경 해줬습니다.

그래서 A-Z까지 Dictionary에 값을 넣어주도록 해서 초기화 해줬습니다.

그리고 dictionary에 넣을 inputString과 현재 값이 dictionary에 있는지 판단해주는 searchString으로 나눠줬습니다.

예를들어 K A 라면 KA 가 저장되고 그 다음 A로 넘어가게 됩니다. 그리고 마지막 문자일 때에 대한 처리를 해줬습니다.

 

** 새롭게 알게 된 사실 **

reduce의 새로운 기능!!!

reduce는 하나씩 검사하면서 이전의 초기명령에 더해주는 기능 입니다.

var dic = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".reduce(into: [String: Int](), { d, s in
       d[String(s)] = d.count+1
   })
    
//결과
["Q": 17, "X": 24, "K": 11, "S": 19, "Y": 25, "U": 21, "R": 18, "H": 8, "B": 2, "P": 16, "Z": 26, "G": 7, "I": 9, "O": 15, "F": 6, "E": 5, "V": 22, "W": 23, "D": 4, "A": 1, "J": 10, "L": 12, "T": 20, "N": 14, "C": 3, "M": 13]

그런데 이렇게 [String, Int]() 형 딕셔너리를 초기값으로 넣어줘서 하나씩 넣어주는게 가능해서 매우 놀라웠습니다.

마찬가지로 reduce안에 stack을 넣어주면, 이러한 기능이 가능합니다.

let msg = "ABABABABABABABAB"
let result = msg.reduce(into: [Character]() ) { (stack, char) in
    return stack.append(char)
}

//결과
["A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B"]

 

728x90
반응형

댓글