LeetCode - 13. Roman to Integer - 思考if-else与switch的比较 - ( C++ ) - 解题报告

1.题目

原题:Given a roman numeral, convert it to an integer.

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

Subscribe to see which companies asked this questio

解析:给出一个罗马数字,要求把其转换为一个整数。输入范围在1到3999内。

 

 

罗马数字的规则如下:

罗马数字 I V X L C D M
代表的阿拉伯数字 1 5 10 50 100 500 1000

其中又有:

  1. 基本数字 Ⅰ、X 、C 中的任何一个、自身连用构成数目、或者放在大数的右边连用构成数目、都不能超过三个;放在大数的左边只能用一个;
  2. 不能把基本数字 V 、L 、D 中的任何一个作为小数放在大数的左边采用相减的方法构成数目;放在大数的右边采用相加的方式构成数目、只能使用一个;
  3. I只能用在V和X左边;
  4. X只能用在L和C左边;
  5. C只能用在D和M左边。

举例:

·个位数举例
Ⅰ-1、Ⅱ-2、Ⅲ-3、Ⅳ-4、Ⅴ-5、Ⅵ-6、Ⅶ-7、Ⅷ-8、Ⅸ-9
·十位数举例
Ⅹ-10、Ⅺ-11、Ⅻ-12、XIII-13、XIV-14、XV-15、XVI-16、XVII-17、XVIII-18、XIX-19、XX-20、XXI-21、XXII-22、XXIX-29、XXX-30、XXXIV-34、XXXV-35、XXXIX-39、XL-40、L-50、LI-51、LV-55、LX-60、LXV-65、LXXX-80、XC-90、XCIII-93、XCV-95、XCVIII-98、XCIX-99
·百位数举例
C-100、CC-200、CCC-300、CD-400、D-500、DC-600、DCC-700、DCCC-800、CM-900、CMXCIX-999
·千位数举例
M-1000、MC-1100、MCD-1400、MD-1500、MDC-1600、MDCLXVI-1666、MDCCCLXXXVIII-1888、MDCCCXCIX-1899、MCM-1900、MCMLXXVI-1976、MCMLXXXIV-1984、MCMXC-1990、MM-2000、MMMCMXCIX-3999
参考:罗马数字

 

2.思路

有两种思路,一种是直接if-else的模式(这种模式runtime比第二种好),第二种是switch,第二种的runtime表现并不好。这引发了我对 if - else 和 switch的好奇,还好已经有人总结出了这部分的内容:

由此看来,switch有点以空间换时间的意思,而事实上也的确如此。
1.当分支较多时,当时用switch的效率是很高的。因为switch是随机访问的,就是确定了选择值之后直接跳转到那个特定的分支,但是if。。else是遍历所以得可能值,知道找到符合条件的分支。如此看来,switch的效率确实比ifelse要高的多。
2.由上面的汇编代码可知道,switch...case占用较多的代码空间,因为它要生成跳表,特别是当case常量分布范围很大但实际有效值又比较少的情况,switch...case的空间利用率将变得很低
3.switch...case只能处理case为常量的情况,对非常量的情况是无能为力的。例如 if (a > 1 && a < 100),是无法使用switch...case来处理的。所以,switch只能是在常量选择分支时比ifelse效率高,但是ifelse能应用于更多的场合,ifelse比较灵活

参考:switch与ifelse的效率问题

 

3.两种思路的代码

第一种:

class Solution {
public:
    int romanToInt(string s) {
        int ans=0,m=s.size();
        char ch;
        for(int i=0;i<m;i++){
            if(s[i]=='M') ans+=1000;
            else if(s[i]=='D') ans+=500;
            else if(s[i]=='C') {
                if((s[i+1]=='D'||s[i+1]=='M')&&i+1<m) ans-=100;
                else ans+=100;
            }
            else if(s[i]=='X') {
                if((s[i+1]=='L'||s[i+1]=='C')&&i+1<m) ans-=10;
                else ans+=10;
            }
            else if(s[i]=='V')  ans+=5;
            else if(s[i]=='I') {
                if((s[i+1]=='V'||s[i+1]=='X')&&i+1<m) ans--;
                else ans++;
            }
            else if(s[i]=='L') ans+=50;
        }
        return ans;
    }
};

 

第二种:

class Solution {
public:
    
        int value(char ch)
{
    switch (ch) {
    case 'I':
        return 1;
    case 'V':
        return 5;
    case 'X':
        return 10;
    case 'L':
        return 50;
    case 'C':
        return 100;
    case 'D':
        return 500;
    case 'M':
        return 1000;
    }
    return 0;
}

int romanToInt(string s)
{
    int ans = 0;
    char max = 'I';
    for (int i = s.size()-1; i >= 0; --i) {
        if (value(s[i]) >= value(max)) {
            max = s[i];
            ans += value(s[i]);
        } else {
            ans -= value(s[i]);
        }
    }
    return ans;
}
    
};

  

 

posted @ 2016-10-28 22:51  rgvb178  阅读(807)  评论(0编辑  收藏  举报