罗马数字与阿拉伯数字的相互转化

题目

1

Given an integer, convert it to a roman numeral.

Input is guaranteed to be within the range from 1 to 3999.

2

Given a roman numeral, convert it to an integer.

Input is guaranteed to be within the range from 1 to 3999.


这两道题就是要我们在1~3999(为什么小于4000呢?)的范围内将用阿拉伯数字表示的整数与用罗马数字表示的数相互转换。

罗马数字

在将这两者转化之前,我们需要先了解一下罗马数字及其规则。

(罗马数字的起源,变化以及发展跟我们的主题无关,想要知道的自己上网查找。)

罗马数字一共有7个基本符号,分别为:I(1)、V(5)、X(10)、L(50)、C(100)、D(500)和M(1000),括号内的值表示其大小。注意:罗马数字并没有表示0的符号。

规则

1. 相同的数字连写、所表示的数等于这些数字相加得到的数。 如 III表示 3,XX表示20。但是,一般情况下,连写不能超过3次,V、L和D不能连写。

2. 小的数字在大的数字的右边,所表示的数等于这些数字相加得到的数。 如 VI 表示 6。

3. 小的数字在大的数字的左边,所表示的数等于大数减小数得到的数。 如 IX 表示 9, CD表示400。但是,这个仅限于I在V或者X的左边, X在L或C的左边,C在D或M的左边。例如99表示成 XCIX,不能表示为 IC。而且左减数字只能为一位。例如8表示成VII,不能表示成IIX。

4. 在一个数的上面画一条横线、表示这个数扩大 1000 倍。(由于在这两道题目中,无法表示出来,因此最大只能表示3999,要表示5000就只能在V上面加上横线)。

个人理解

看了上面的规则后,其实有些人对于罗马数字的表示还可能云里雾里的。如果你把IV(4), IX(9), XL(40),XC(90),CD(400),CM(900)看成一个数字。在将一个数表示成罗马数字的时候,按照从左到右的写法,从大到小选择罗马数字符号就可以了。

例如,748 =》 DCC(700) + XL(40) + VIII =》 DCCXLVIII

           999 =》 CM(900) + XC(90) + IX =》 CMXCIX

代码

在int->roman中,我用一个表存储十进制数上每个位上的数字对应的罗马数字。在转换的时候,只要求解出每个位置上的数字,再查表后将得到的字符连接起来就可以得出结果。

在roman->int中,用一个int类型的变量表示罗马数字代表的值,若使用查表的方法需要先对字符串进行分割,有点麻烦,直接利用规则2和规则3,若字符str[i]表示的值小于字符str[i+1]表示的值,就减去str[i]的值,否则加上str[i+1]的值。

#include<cmath>
class Solution {
public:
    string intToRoman(int num) {
        // table表存储十进制数上每个位所表示的罗马数字
        // 例如, 365 中 百位上的 3 大小为 table[2][3] = CCC
        string table[4][10] = {
            {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"},
            {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"},
            {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"},
            {"", "M", "MM", "MMM", "", "", "", "", "", ""}
        };
        string roman_numeral = "";
        roman_numeral += table[3][num / 1000];
        num %= 1000;
        roman_numeral += table[2][num / 100];
        num %= 100;
        roman_numeral += table[1][num / 10];
        num %= 10;
        roman_numeral += table[0][num];
        return roman_numeral;
    }
};
#include <map>
class Solution {
public:
    int romanToInt(string s) {
        map<char, int> mymap = {
            {'I', 1}, {'V', 5}, {'X', 10}, {'L', 50}, {'C', 100}, {'D', 500}, {'M', 1000}
        };
        int result = 0, i = 0, temp;
        for (i = 0; i < s.length() - 1; i++) {
            temp = mymap[s[i]];
            if (temp < mymap[s[i + 1]]) {
                result -= temp;
            } else {
                result += temp;
            }
        }
        result += mymap[s[i]];
        return result;
    }
};


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值