Roman to Integer(罗马数字转换为整数)

Given a roman numeral, convert it to an integer.(给定一个罗马数字,将其转换成整数)
Input is guaranteed to be within the range from 1 to 3999.(输入范围在1-3999内)

1.个人分析
这道题本质上应该与将字符串转化为整型一样,可以将atoi中实现的方法应用到这里。

思路:
罗马数字的七个基本字符为:I(1)、V(5)、X(10)、L(50)、C(100)、D(500)、M(1000),它们的组合规则如下:
除I、X、C位于大数后作为加数,位于大数前作为减数外,一般把若干罗马基本数字写在一起,它表示的数字等于各个数字的和。
注意点:

  • I、X、C在大数右边(即相加时)不能连续超过三个,在大数左边(即相减时)只能用一个。
  • V、L、D不能用于大数左边(相减),只能用于大数右边(相加),且只使用一个。
  • V、X左边小数只用I;L、C左边小数只用X;D、M左边小数只用C。

2.个人解法

int romanToInt(string s)
{
    int len = s.length();
    if(0 == len)
        return 0;

    map<char, int>roman;
    roman['I'] = 1;
    roman['V'] = 5;
    roman['X'] = 10;
    roman['L'] = 50;
    roman['C'] = 100;
    roman['D'] = 500;
    roman['M'] = 1000;

    int sum = 0;
    int i;
    for (i=1; i<len; ++i)
    {
        if('I' == s[i-1] && roman[s[i]] > roman[s[i-1]])            
            sum += (-roman[s[i-1]]);            
        else if('X' == s[i-1] && roman[s[i]] > roman[s[i-1]])
            sum += (-roman[s[i-1]]);
        else if('C' == s[i-1] && roman[s[i]] > roman[s[i-1]])
            sum += (-roman[s[i-1]]);
        else
            sum += roman[s[i-1]];
    }
    sum += roman[s[i-1]];

    return sum;
}

3.参考解法

int romanToInt(string s) 
{
    int len = s.length();
    if(0 == len)
        return 0;       

    unordered_map<char, int> roman = {
            { 'I', 1 },
            { 'V', 5 },
            { 'X', 10 },
            { 'L', 50 },
            { 'C', 100 },
            { 'D', 500 },
            { 'M', 1000 } 
    };

    int sum = 0;
    int pre = 0;
    for (int i=len-1; i>=0; --i)
    {
        int cur = roman[s[i]];
        if(cur < pre)
            sum -= cur;
        else
            sum += cur;
        pre = cur;
    }

    return sum;
}

4.总结
自己的解法与他人解法的思路是一致的,都是利用哈希表来保存罗马字母对应的值,然后扫描字符串进行累加,这里需要判断做减法的情形。这里有个细节值得推敲,第一种解法中是利用下标法进行初始化,第二种解法是在定义哈希表时就进行赋值;第一种初始化在VS2010中是正确的,第二种不能通过编译,但在leetcode可以通过编译和运行,所有这很可能是在C++11后的标准中才支持的;另外两种初始化方式的运行效率相差较大,第二种运行了60ms,第一种运行了80,提高了四分之一效率。

PS:

  • 题目的中文翻译是本人所作,如有偏差敬请指正。
  • “个人分析”和“个人解法”均是本人最初的想法和做法,不一定是对的,只是作为一个对照和记录。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值