標籤:pre hot man ... detail 報告 inline ase his
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 |
其中又有:
- 基本數字 Ⅰ、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 - 思考if-else與switch的比較 - ( C++ ) - 解題報告