본문 바로가기
알고리즘/문제풀이

[LeetCode] (Swift) 13. Roman to Integer

by venniek 2022. 9. 14.

문제 보러 가기

문제

로마 숫자는 7가지 다른 문자로 표현된다: I, V, X, L, C, D, M

각 문자가 나타내는 숫자는 다음과 같다.

예를 들어,

21 + 1 이므로 II

1210 + 2 이므로 XII

2720 + 5 + 2 이므로 XXVII.

로마 숫자는 주로 왼쪽부터 오른쪽으로, 큰 숫자에서 작은 숫자로 쓴다. 하지만 4IIII 로 쓰지 않고 1을 5 앞에 쓰고 5 - 1 을 해 IV 로 쓴다. 같은 원리로 910 - 1 이므로 IX 로 쓴다. 빼기를 사용하는 여섯 가지 경우가 있다.

  • VX 앞에 I : 4, 9
  • LC 앞에 X: 40, 90
  • DM 앞에 C: 400, 900
  • → 로마 숫자가 주어지면 정수로 변환해라.

    풀이

    • 오른쪽으로 가면 숫자가 작아져야 하는데 여섯 가지 예외를 만나면 작은 숫자 오른쪽에 큰 숫자가 나올 수 있다. 이 경우에는 작은 숫자를 빼야 한다.
    • 앞에서부터 뒤로 가면서 현재 숫자가 다음 숫자보다 작으면 빼고, 크거나 같으면 더하면 된다.
    • 이렇게 하면 현재 인덱스가 마지막 인덱스인지 검사해야 하고, 다음 숫자를 비교할 때 Dictionary 를 한 번 더 써야 한다. (안 되는 건 아니지만 코드가 길어진다)
    • 반대로 생각해서, 뒤에서 앞으로 오면서 뒤의 숫자를 저장해둔 변수를 불러와서 현재 숫자와 비교하고, 현재 숫자가 작으면 빼고 크거나 같으면 더한다.

    → 뒤에서 앞으로 오면서 현재 숫자가 뒤 숫자보다 작으면 빼주고, 크거나 같으면 더해준다.

    코드

    class Solution {
        func romanToInt(_ s: String) -> Int {
            let m: [Character: Int] = ["I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000]
            var prev = 0, ans = 0
            let str = Array(s)
            let len = str.count
    
            for i in 1...len {
                let now = m[str[len - i]]!
                ans += now >= prev ? now : -now
                prev = now
            }
            return ans
        }
    }
    • 각 문자와 정수값은 Dictionary에 넣어서 한 번에 변환할 수 있게 해준다. (m)
    • 첫 문자는 무조건 넣어줘야 하니 최솟값인 I보다 작은 0부터 비교를 시작한다. (prev)
    • 인덱스 참조가 쉽도록 StringArray 로 바꿔준다. (str)


    '알고리즘 > 문제풀이' 카테고리의 다른 글

    [프로그래머스] (Swift) 순위  (2) 2022.11.16
    [프로그래머스] (Swift) 위장  (1) 2022.10.05
    [백준] (Swift) 2675 문자열 반복  (0) 2022.07.11
    [백준](Swift) 1차원 배열  (0) 2022.06.04
    [백준](Swift) 반복문  (0) 2022.05.28

    댓글