boraBong

[Swift] [3차] 압축 문제 풀이 [Programmers - Level2 (2018 KAKAO BLIND RECRUITMENT)] 본문

iOS/Algorithm

[Swift] [3차] 압축 문제 풀이 [Programmers - Level2 (2018 KAKAO BLIND RECRUITMENT)]

보라봉_ 2023. 3. 30. 20:40
728x90

💬 문제

https://school.programmers.co.kr/learn/courses/30/lessons/17684

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 


💬 Idea

  • 먼저 msg 문자열을 Array형태로 변환한 뒤 배열을 뒤집는다.
    • 가장 첫번째 문자를 popLast()하기 위해 (배열을 뒤집지 않고 removeFirst()를 수행하게 되면 효율성이 아주 떨어지기 때문이다)
1. 현재 입력과 일치하는 가장 긴 문자열을 찾기 위해 msg의 마지막 원소가 있을 때까지 popLast()를 수행한다.
   -> popLast()한 값을 word 변수에 더해준다.
	✅ 이 때 word + c(msg의 last값)가 사전에 있다면 또 다음 긴 문자를 찾기 위해 반복한다.
	✅ 이 때 word + c(msg의 last값)가 사전에 없다면 해당 값을 사전에 등록하고 반복문을 멈춘다.
	   -> 사전에 등록할 때 사전의 마지막 값을 + 1 하여 업데이트 해준다.

2. 현재 입력과 일치하는 가장 긴 문자열은 word 변수와 일치하므로 ans 배열에 사전의 word 값을 append해준다.
3. msg 배열이 빌 때까지 1,2 과정을 반복한다.

 


💬 풀이

func solution(msg: String) -> [Int] {
    var msg = Array(msg).reversed().map({ String($0) })
    var dict: [String: Int] = ["A": 1, "B": 2, "C": 3, "D": 4, "E": 5, "F": 6, "G": 7, "H": 8, "I": 9, "J": 10, "K": 11, "L": 12, "M": 13, "N": 14, "O": 15, "P": 16, "Q": 17, "R": 18, "S": 19, "T": 20, "U": 21, "V": 22, "W": 23, "X": 24, "Y": 25, "Z": 26]
    var dictLastVal = 26
    var ans: [Int] = []
    
    while !msg.isEmpty {
        var word = ""
        while let w = msg.popLast() {
            word += w
            if let c = msg.last {
                if dict[word + c] == nil {
                    dictLastVal += 1
                    dict[word + c] = dictLastVal
                    break
                }
            }
        }
        ans.append(dict[word]!)
    }
    
    return ans
}

https://github.com/hwangJi-dev/swiftAlgorithm/blob/main/Programmers/Programmers/level2/%5B3%EC%B0%A8%5D%20%EC%95%95%EC%B6%95.swift

 

GitHub - hwangJi-dev/swiftAlgorithm: Algorithm Practice with Swift

Algorithm Practice with Swift. Contribute to hwangJi-dev/swiftAlgorithm development by creating an account on GitHub.

github.com

 


💬 더 나은 방법?

  • 문제를 풀면서 사전에 이미 정의되어있는 1개의 단어들을 일일이 초기화해줬는데,
    Unicode.Scalar를 통해 숫자를 이용해서 알파벳을 차례대로 표현할 수 있다는 걸 알게되었다.
    • 대문자 알파벳 A를 Unicode.Scalar(65)로 표현할 수 있다.
    • 이후 차례대로 26개의 알파벳을 표현한다.
var dict: [String: Int] = [:]

for i in 1...26 {
    if let scalar = Unicode.Scalar(64 + i) {
        dict[scalar.description] = i
    }
}

// dict
// ["A": 1, "B": 2, "C": 3, "D": 4, "E": 5, "F": 6, "G": 7, "H": 8, "I": 9, "J": 10, "K": 11, "L": 12, "M": 13, "N": 14, "O": 15, "P": 16, "Q": 17, "R": 18, "S": 19, "T": 20, "U": 21, "V": 22, "W": 23, "X": 24, "Y": 25, "Z": 26]

 


💬 알게된 것

✅ Unicode.Scalar

  • 크기가 가변적인 String 문자열을 하나하나 개별적으로 접근하기 위한 방법.
  • Unicode기반 21-bit 코드
  • UTF-32랑 거의 동일하다.
  • 하나 이상의 Unicode Scalar가 모여 Character를 이룬다.
  • 숫자 표현에서 직접 유니코드 스칼라 값을 생성할 수 있다.
    • Unicode.Scalar(65) // “A”

<참고>

https://velog.io/@haze5959/Swift-Unicode-Scalar-그리고-문자열-count-시간-복잡도-관계

 

반응형
Comments