Computer >> 컴퓨터 >  >> 프로그래밍 >> 프로그래밍

10진수를 로마 숫자로 변환하는 방법

로마 숫자란 무엇인가?

로마 숫자는 자릿값(위치)에 따라 값이 달라지지 않는 비위치적(non-positional) 기수법입니다. 여러 개의 기호를 나란히 조합하여 하나의 수를 표현하며, 각 기호의 값을 모두 더해 전체 숫자를 나타냅니다.

예를 들어 75라는 숫자는 50 + 10 + 10 + 5로 분해할 수 있으며, 이를 로마 숫자로 표현하면 LXXV가 됩니다.

이 글에서는 10진수 형태로 주어진 숫자를 로마 숫자 문자열로 변환하는 방법과, 이를 구현한 알고리즘 및 C++ 코드를 살펴보겠습니다.

로마 숫자 기호와 값

로마 숫자에서 사용되는 기호와 그 값은 다음과 같습니다.

기호
I1
IV4
V5
IX9
X10
XL40
L50
XC90
C100
CD400
D500
CM900
M1000
MMMM4000
V'5000

이 표를 활용하면 주어진 숫자에 해당하는 로마 숫자를 쉽게 찾을 수 있습니다. 핵심은 숫자에서 뺄 수 있는 가장 큰 기호 값을 찾아 차감하고, 남은 값에 대해 같은 과정을 반복하는 것입니다.

입력 및 출력 예시

Input:
Decimal number: 3569
Output:
The Roman equivalent of 3569 is: MMMDLXIX

알고리즘

변환 함수는 다음과 같이 정의됩니다.

decToRoman(nuList, num)

입력: 기호와 값이 담긴 목록(nuList), 로마 숫자로 변환할 수(num)
출력: 주어진 숫자에 해당하는 로마 숫자

동작 과정은 다음과 같습니다.

Begin
    if num ≠ 0, then
        max := num보다 크지 않은 최대 기호 값을 찾음
        display the nuList[max].symbol
        num := num – nuList[max].value
        decToRoman(nuList, num)  // 남은 값에 대해 재귀 호출
End

이 알고리즘은 매 단계에서 처리 가능한 가장 큰 값을 선택하는 그리디(greedy) 방식으로 동작하며, 남은 숫자가 0이 될 때까지 재귀적으로 반복합니다.

C++ 구현 예제

#include<iostream>
using namespace std;

struct numeral {
    string sym;
    int val;
};

int maxNume(numeral nu[], int num) {
    int index;
    for(int i = 0; i<15; i++)  // 배열에는 15개의 기호가 있음
        if(nu[i].val<= num)
            index = i;
    // num보다 크지 않은 가장 큰 값의 인덱스 반환
    return index;
}

void decToRoman(numeral nu[], int num) {
    int max;
    if(num != 0) {
        max = maxNume(nu, num);
        cout << nu[max].sym;
        num -= nu[max].val;  // 숫자 감소
        decToRoman(nu, num);  // 재귀적으로 기호 출력
    }
}

int main() {
    int number;
    numeral nume[15] = {{"I",1},{"IV",4},{"V",5},{"IX",9},
        {"X",10},{"XL",40},{"L",50},{"XC",90},
        {"C",100},{"CD",400},{"D",500},{"CM",900},
        {"M",1000},{"MMMM",4000},{"V'",5000}
    };
    cout << "Enter a decimal number: "; cin >> number;

    if(number >0 && number <= 5000) {  // 입력 범위 검사
        cout<<"The Roman equivalent of " << number<<" is: ";
            decToRoman(nume, number);
    }else {
        cout << "Invalid Input";
    }
}

실행 결과

Enter a decimal number: 3569
The Roman equivalent of 3569 is: MMMDLXIX

정리

10진수를 로마 숫자로 변환하는 문제는 기호와 값의 대응표를 준비한 뒤, 큰 값부터 차감해 나가는 그리디 알고리즘으로 해결할 수 있습니다. 위 코드처럼 재귀 함수를 사용하면 로직이 간결해지며, 입력 범위 검사를 추가하면 잘못된 입력도 안전하게 처리할 수 있습니다.