小试牛刀————罗马数字与整数的相互转换

一、题目描述:

罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
字符与数值的对应关系如下:
I -> 1, V -> 5, X -> 10, L -> 50, C -> 100, D -> 500, M -> 1000
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。
数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。
这个特殊的规则只适用于以下六种情况:
I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。

1、将罗马数字转换成整数

例:
输入: “MCMXCIV”
输出: 1994
解释: M = 1000, CM = 900, XC = 90, IV = 4.

2、将整数转换成罗马数字

例:
输入: 1994
输出: “MCMXCIV”
解释: M = 1000, CM = 900, XC = 90, IV = 4.

二、题目分析:

1、罗马数字转整数:

  • 由题意可知,如果当前这个罗马数字小于后一个,则减去这个罗马数字对应的整数值,反之则加上对应的值;
  • 因此按照这个思路,只要将罗马数字从头遍历到尾,就可以得到相应的整数值。(用switch语句记录每个罗马数字代表的整数值)

2、整数转罗马数字:

  • 由题意可知,要把整数转换为罗马数字,我们需要将这个整数的每一个位(个、十、百、千)上的数字,都转化为它所对应的罗马数字,因为罗马数字个、十、百、千位上的数字表示都不一样;
  • 则先求出整数的位数(n /= 10),然后再求出每一位对应的整数数字;
  • 用switch语句得到数字0~9在罗马数字中的个、十、百、千位所对应的罗马数字。

三:代码详解:

1、罗马数字转整数:

int val(char s)//记录罗马数字对应的整数值
{
    int val = 0;
    switch (s)
    {
    case 'I': val = 1; break;
    case 'V': val = 5; break;
    case 'X': val = 10; break;
    case 'L': val = 50; break;
    case 'C': val = 100; break;
    case 'D': val = 500; break;
    case 'M': val = 1000; break;
    }
    return val;
}

int romanToInt(string s) 
{
    int len = s.size();
    int sum = 0;
    for (int i = 0; i < len; i++)
    {
        if (val(s[i]) >= val(s[i + 1]))	//大于等于后一个则加
        {
            sum += val(s[i]);
        }
        else							//小于后一个则减
        {
            sum -= val(s[i]);	
        }
    }
    return sum;
}

int main()
{
    string s = "MMMCMXCIX";

    cout << romanToInt(s) << endl;
    return 0;
}

2、整数转罗马数字:

int size(int n)		//求整数的位数
{
    int size = 0;
    while (n)
    {
        n /= 10;
        size++;
    }
    return size;
}

string str(int _size,int m)		//数字0~9在罗马数字中的个、十、百、千位所对应的罗马数字
{
    string str;
    if (_size == 1)		//个位
    {
        switch (m)
        {
        case 1: str = "I"; break;
        case 2: str = "II"; break;
        case 3: str = "III"; break;
        case 4: str = "IV"; break;
        case 5: str = "V"; break;
        case 6: str = "VI"; break;
        case 7: str = "VII"; break;
        case 8: str = "VIII"; break;
        case 9: str = "IX"; break;
        }
    }
    else if (_size == 2)		//十位
    {
        switch (m)
        {
        case 1: str = "X"; break;
        case 2: str = "XX"; break;
        case 3: str = "XXX"; break;
        case 4: str = "XL"; break;
        case 5: str = "L"; break;
        case 6: str = "LX"; break;
        case 7: str = "LXX"; break; 
        case 8: str = "LXXX"; break;
        case 9: str = "XC"; break;
        }
    }
    else if (_size == 3)		//百位
    {
        switch (m)
        {
        case 1: str = "C"; break;
        case 2: str = "CC"; break;
        case 3: str = "CCC"; break;
        case 4: str = "CD"; break;
        case 5: str = "D"; break;
        case 6: str = "DC"; break;
        case 7: str = "DCC"; break;
        case 8: str = "DCCC"; break;
        case 9: str = "CM"; break;
        }
    }
    else if (_size == 4)		//千位
    {
        switch (m)
        {
        case 1: str = "M"; break;
        case 2: str = "MM"; break;
        case 3: str = "MMM"; break;        
        }
    }

    return str;
}

string intToRoman(int n)
{
    int _size = size(n);//整形数字的位数
    string _s;
    if (_size > 4)
    {
        return 0;
    }
    while (_size > 0)
    {
        int k = pow(10, _size-1);
        int m = n/k;       
        _s += str(_size, m);
        n %= k;
        _size--;
    }
    return _s;
}

int main()
{
    int n = 1994;
    cout << intToRoman(n) << endl;
}

猜你喜欢

转载自blog.csdn.net/djh971102/article/details/89109503