[LeetCode] 13. Roman to Integer (easy)

Hwanhoon KIM·2023년 5월 23일
0

Leetcode

목록 보기
4/4

제일 쉬운건데 나는 제일 어렵게 풀었다...

Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M.

Symbol Value
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
For example, 2 is written as II in Roman numeral, just two ones added together. 12 is written as XII, which is simply X + II. The number 27 is written as XXVII, which is XX + V + II.

Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used:

I can be placed before V (5) and X (10) to make 4 and 9.
X can be placed before L (50) and C (100) to make 40 and 90.
C can be placed before D (500) and M (1000) to make 400 and 900.
Given a roman numeral, convert it to an integer.

Example 1:

Input: s = "III"
Output: 3
Explanation: III = 3.
Example 2:

Input: s = "LVIII"
Output: 58
Explanation: L = 50, V= 5, III = 3.
Example 3:

Input: s = "MCMXCIV"
Output: 1994
Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.

Constraints:

1 <= s.length <= 15
s contains only the characters ('I', 'V', 'X', 'L', 'C', 'D', 'M').
It is guaranteed that s is a valid roman numeral in the range [1, 3999].

function romanToInt(s) {
  // 매개변수 s(string)를 받아서 단어 한글자씩 array로 만든다.
    let x = s.split('')
    // 일종에 필터다. 다음 어레이에 있는 요소만 들어올 수 있다.
    ruleArr = ['I','V','X','L','C','D','M']
  // 필터 세팅이다. 만약 매개변수 s에 ruleArr에 있는 요소 말고 다른 것이 오면 tempNum 카운터가 1이라도 증가하고, 결국 tempNum이 0보다 커지면 return하게끔 만들었다.
    let tempNum = 0;
    // 반복문을 두 개 겹쳐서 중복되는것을 찾는 걸 구현하려고 했다.
    x.forEach(letter => {
        ruleArr.forEach(filter => {
            if (letter !== filter && letter !== ruleArr[0] && letter !== ruleArr[1] && letter !== ruleArr[2] && letter !== ruleArr[3] && letter !== ruleArr[4] && letter !== ruleArr[5] && letter !== ruleArr[6] ) {
                tempNum++
            }
        });
    })
    // 매개변수의 길이가 1보다 작거나 15보다 크면 return 하게 했다. (조건 1 충족)
    if (s.length < 1 || s.length > 15) {
        return
    } else if (tempNum > 0) { // 위에 말한 필터 세팅카운터가 증가하면 리턴한다.
        return
    } else {
    let temp = 0; // temp는 이 함수의 핵심 카운터이다.
    
    // I와 X와 C의 인덱스를 찾는다.
    const indexOf_I = x.findIndex(el => el === 'I');
    const indexOf_X = x.findIndex(el => el === 'X');
    const indexOf_C = x.findIndex(el => el === 'C');
    // IV는 4를 추가하고  IX 는 9를 추가한다.
    if (indexOf_I !== -1 && x[indexOf_I+1] === 'V' || indexOf_I !== -1 && x[indexOf_I+1] === 'X' ) {
        if (x[indexOf_I+1] === 'V') {
            temp += 4;
            x.splice(indexOf_I, 2);
        } else {
            temp += 9;
            x.splice(indexOf_I, 2);
        }
    }
    // XL 는 40을 추가하고, XC 는 90을 추가한다.
    if (indexOf_X !== -1 && x[indexOf_X+1] === 'L' || indexOf_X !== -1 && x[indexOf_X+1] === 'C' ) {
        if (x[indexOf_X+1] === 'L') {
            temp += 40;
            x.splice(indexOf_X, 2);
        } else {
            temp += 90;
            x.splice(indexOf_X, 2);
        }
    }
    // CD 는 400을 추가하며, CM 은 900을 추가한다.
    if (indexOf_C !== -1 && x[indexOf_C+1] === 'D' || indexOf_C !== -1 && x[indexOf_C+1] === 'M' ) {
        if (x[indexOf_C+1] === 'D') {
            temp += 400;
            x.splice(indexOf_C, 2);
            console.log(temp, 1)
        } else {
            temp += 900;
            x.splice(indexOf_C, 2);
            console.log(temp, 2)
        }
    }
	// 그리고 나머지 공식을 적용하였다.
    for (let letter of x) {
        if (letter === 'I') {
            temp += 1;
        } else if (letter === 'V') {
            temp += 5;
        } else if (letter === 'X') {
            temp += 10;
        } else if (letter === 'L') {
            temp += 50;
        } else if (letter === 'C') {
            temp += 100;
        } else if (letter === 'D') {
            temp += 500;
        } else if (letter === 'M') {
            temp += 1000;
        }
    }
    // 조건 3 충족
    if (temp > 0 && temp < 4000) {
        console.log(temp)
        return temp
    } else {
        return
    }
    }
    
}

const a = "D"
romanToInt(a);

그.. 근데 내가 본 정답은 충격적이게 간단했다.

function romanToInt(s) {
    const romanValues = {
        'I': 1,
        'V': 5,
        'X': 10,
        'L': 50,
        'C': 100,
        'D': 500,
        'M': 1000
    };
    
    let result = 0;
    
    for (let i = 0; i < s.length; i++) {
        const currentSymbol = s[i];
        const currentValue = romanValues[currentSymbol];
        const nextSymbol = s[i + 1];
        const nextValue = romanValues[nextSymbol];
        
        if (nextValue && currentValue < nextValue) {
            result += nextValue - currentValue;
            i++;
        } else {
            result += currentValue;
        }
    }
    
    return result;
}

// Example usage:
console.log(romanToInt("III"));      // Output: 3
console.log(romanToInt("LVIII"));    // Output: 58
console.log(romanToInt("MCMXCIV"));  // Output: 1994

romanValues라는 객체를 만든다. 이 객체는 로마 숫자 기호를 해당하는 값으로 매핑하는 역할을 한다. 예를 들어 'I'는 1로 매핑된다.

result라는 변수를 0으로 초기화한다. 이 변수는 최종 결과 값을 저장할 변수다.

for 반복문을 사용하여 입력 문자열의 각 문자를 순회한다. i 변수는 현재 문자의 인덱스를 나타낸다.

currentSymbol 변수에는 현재 문자를 할당한다.

currentValue 변수에는 currentSymbol에 해당하는 값을 romanValues 객체에서 찾아 할당한다.

nextSymbol 변수에는 다음 문자를 할당한다. 이를 위해 s[i + 1]을 사용하며, 다음 문자가 없는 경우 undefined가 할당된다.

nextValue 변수에는 nextSymbol에 해당하는 값을 romanValues 객체에서 찾아 할당한다.

조건문을 사용하여 현재 값이 다음 값보다 작은 경우를 체크한다. 또한, nextValue가 undefined가 아닌지도 확인 해야한다. 이를 통해 로마 숫자에서 뺄셈이 필요한 경우를 처리합니다. 예를 들어 'IV'는 5 - 1로 계산되어야 한다.

뺄셈이 필요한 경우, result에 nextValue - currentValue를 더하고, 현재 인덱스를 1 증가시켜 다음 문자를 건너뛴다. 이는 다음 문자가 이미 처리되었기 때문에 현재 문자와 함께 처리하기 위해서이다.

뺄셈이 필요하지 않은 경우, result에 currentValue를 더한다.

반복문이 끝나면 최종 result 값을 반환한다...

멀고도 먼 코딩의 세계

profile
Fullstack Developer, I post about HTML, CSS(SASS, LESS), JavaScript, React, Next, TypeScript.

0개의 댓글