[Swift] [88일차] 2520_Character vs String의 Int 형변환

·2025년 3월 7일
0

SwiftAlgorithm

목록 보기
93/105
post-thumbnail

2520. Count the Digits That Divide a Number


문제 설명

  1. 숫자 num이 주어짐
  2. 해당 숫자를 자릿수별로 나눴을 때 나눠지는 자리수의 수를 return해라

문제 풀이

  1. 일단은Int로 주어진 num을 어떻게 분리해서 나눠줄 것이냐이다.
  2. type(of:)print를 찍어보면 Character라고 나온다. Array(String(num)을 통해서 문자열을 배열로 바꾼 형태이기 때문에.
  3. 그래서 이걸 가볍게 계산을 해주면 되는데, 여기서 뭘 얻어갈 것인가?에서
 let k = Int(String(i))!

이 코드에서 볼 수 있듯이 Int(i)!만 단독으로 쓰였을 때, 즉 CharacterInt로 바꾸는 것은 왜 바로 안돼서, 이걸 굳이굳이 Character -> String -> Int 이렇게 String을 꼭 거쳐야하는걸까 ?

최종 제출 코드

class Solution {
    func countDigits(_ num: Int) -> Int {
        var answer = 0
        for i in Array(String(num)) {
//            print(type(of: i)) // Character
            let k = Int(String(i))! // Character 라서 String()으로 바꿔준뒤에 Int로 변경
            if num % k == 0 {
                answer += 1
            }
        }
        return answer
    }
}

타인의 코드

class Solution {
    func countDigits(_ num: Int) -> Int {
        var s = 0
        var f = num
        while f > 0 {
            if num % (f%10) == 0 {
                s += 1
            }
            f /= 10
        }
        return s
    }
}

일단 굳이 나처럼 String으로 바꾸지않고, 자연수 딴에서 해결해준 사례를 볼 수 있었다. 너무 비슷하게 항상 풀이하는 나를 반성하는 계기. ..


왜 Character 타입에서는 Int() 사용이 불가한가 ?

1. CharacterInt의 차이

Swift에서 Character단일 Unicode 스칼라 값이라고 한다. 공식문서 - Character.
여기에서 Character1은 문자(Unicode U+0031)로 취급되는 것인데, 반면 Int는 정수 값 / Character를 바로 Int로 변환하기가 어려운 것이라고 보면 된다. 정확히는 어떻게 매칭해야할지 생긴거만 똑같지 인지를 못한다는 것이다.

2. Int 초기화는 String 기반

Swift 공식 문서에 따르면, Int의 초기화는 String을 입력으로 받아 숫자로 변환합니다(Swift Docs: Int.init):

init?(_ description: String)

하지만 Character를 직접 받는 초기화 메서드는 없습니다. 따라서 CharacterInt로 변환하려면:

  • String(i)CharacterString으로 변환.
  • Int(String(i))StringInt로 변환.

대안책 wholeNumberValue ?

Character 타입은 wholeNumberValue 을 사용할 수 있는데, 아래 사진과 같이 엄청 똑똑하게 사용이 가능하다 ! (Swift Docs: Character.wholeNumberValue):

이를 활용한 코드 개선

class Solution {
    func countDigits(_ num: Int) -> Int {
        var answer = 0
        for i in Array(String(num)) {
            if let k = i.wholeNumberValue { // String 변환 없이 바로 Int로
                if num % k == 0 {
                    answer += 1
                }
            }
        }
        return answer
    }
}

wholeNumberValue의 작동 원리

wholeNumberValue는 Character의 단일 Unicode 값을 읽고, 그것이 "0"부터 "9" (U+0030 ~ U+0039)에 해당하는지 확인합니다. 만약 해당하면, Unicode 값에서 "0"의 값(U+0030, 즉 48)을 빼서 실제 숫자(0~9)를 계산합니다.

  • 작동 순서 (원리) !
  1. Character의 Unicode 스칼라 값을 가져옴 (예: "5" → U+0035).
  2. 이 값이 U+0030(48)에서 U+0039(57) 사이인지 확인.
  3. 숫자라면, scalarValue - 48을 계산해 정수로 변환 (예: 53 - 48 = 5).
  4. 숫자가 아니면 nil 반환.
    wholeNumberValueInt 타입으로 볼 수 있다.

요약

Unicode 스칼라 값을 읽은 다음에 근처 작은 자리수를 빼주면서 일의 자리 즉 - < 0 ~ 9 > 범위로 좁혀서 계산을 해낸다.

profile
기억보단 기록을

0개의 댓글