LeetCode - 13. Roman to Integer - 思考if-else与switch的比较 - ( C++ ) - 解题报告
2016-10-28 22:51
459 查看
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内。
罗马数字的规则如下:
其中又有:
基本数字 Ⅰ、X 、C 中的任何一个、自身连用构成数目、或者放在大数的右边连用构成数目、都不能超过三个;放在大数的左边只能用一个;
不能把基本数字 V 、L 、D 中的任何一个作为小数放在大数的左边采用相减的方法构成数目;放在大数的右边采用相加的方式构成数目、只能使用一个;
I只能用在V和X左边;
X只能用在L和C左边;
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.两种思路的代码
第一种:
第二种:
原题: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 |
基本数字 Ⅰ、X 、C 中的任何一个、自身连用构成数目、或者放在大数的右边连用构成数目、都不能超过三个;放在大数的左边只能用一个;
不能把基本数字 V 、L 、D 中的任何一个作为小数放在大数的左边采用相减的方法构成数目;放在大数的右边采用相加的方式构成数目、只能使用一个;
I只能用在V和X左边;
X只能用在L和C左边;
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; } };
相关文章推荐
- [leetcode] 13. Roman to Integer 解题报告
- [Leetcode] 13. Roman to Integer 解题报告
- LeetCode: String to Integer (atoi) 解题报告
- switch...case 和 if...else效率比较和优化
- 重构if...else...或者switch程序块 为 中介者(Mediator)模式.的思考
- [LeetCode] Integer to Roman 解题报告
- LeetCode解题报告--Roman to Integer
- switch...case和if...else效率比较
- switch...case 和 if...else效率比较和优化
- LeetCode: Reverse Integer 解题报告
- [leetcode] 7. Reverse Integer 解题报告
- LeetCode-Reverse Integer-解题报告
- LeetCode - 268. Missing Number - stable_sort应用实例 - ( C++ ) - 解题报告
- c++学习 day2 循环学习(while do while for) 分支学习(if ; if else; if else if; switch的应用 )
- [LeetCode 解题报告]013. Roman to Integer
- 【LeetCode】Integer to Roman 和 Roman to Integer 解题报告
- 【LeetCode】Integer to Roman 和 Roman to Integer 解题报告
- LeetCode - 459. Repeated Substring Pattern - O(n)和O(n^2)两种思路 - KMP - (C++) - 解题报告
- LeetCode String to Integer (atoi) 解题报告
- switch...case 和 if...else效率比较和优化