下午在FCC(FreeCodeCamp)中文網上做到一道練習題:將給定的數字轉換成羅馬數字。折磨了一個多小時,終於能把基本功能給實現了。過程如下:
關於羅馬數字
羅馬數字的詳細介紹可見百度,或者羅馬數字。這里作一下簡單的介紹(圖片選自羅馬數字):
1.羅馬數字選用7個羅馬字母(大寫)作數字,代表的十進制數字如下:
一些數字用羅馬數字表示為:
2.羅馬數字的計數規則:
(1) 相同數字連寫,則值相加,如III = 3;
(2) 小的數在大的數右邊,也是累加,如VI = 6;
(3) 小的數在大的數左邊,結果為大數減小數,如IV = 4;
(4) 在數的上方划一條橫線,表示擴大1000倍。
一個簡單粗暴的例子:
但是,我們會遇到一些特別的情況:
(1) 3999 = MMMCMXCIX,3999 = MMMDCCCCLXXXXVIIII,兩種結果都是3999,但是我們一般會選擇簡單的,也就是前者;
(2) 同理,3444 = MMMCDXLIV, 3444 = MMMCCCCXXXXIIII,也是選擇前者的方式。
於是,先把1~9的情況都列舉一下:
可以看出,羅馬數字對4和9的處理是不同與其他的。
列舉4、9有關的部分數字:
思路和代碼實現
1.先把數字轉化為相應的羅馬字母,如3999 = MMMDCCCCLXXXXVIIII;
2.再通過replace()將4和9的情況進行替換,使得3999 = MMMCMXCIX。
1 function convert(num) { 2 var newArr = []; 3 var newStr; 4 //先把數字轉化為相應的羅馬字母 5 while(num > 0) { 6 if(num - 1000 >= 0) { 7 newArr.push('M'); 8 num -= 1000; 9 } else if (num - 500 >= 0) { 10 newArr.push('D'); 11 num -= 500; 12 } else if (num - 100 >= 0) { 13 newArr.push('C'); 14 num -= 100; 15 } else if (num - 50 >= 0) { 16 newArr.push('L'); 17 num -= 50; 18 } else if(num - 10 >= 0) { 19 newArr.push('X'); 20 num -= 10; 21 } else if(num - 5 >= 0) { 22 newArr.push('V'); 23 num -= 5; 24 } else if(num - 1 >= 0) { 25 newArr.push('I'); 26 num -= 1; 27 } 28 } 29 newStr = newArr.join(''); 30 //將4和9的情況進行替換 31 newStr = newStr.replace(/VI{4}|LX{4}|DC{4}|I{4}|X{4}|C{4}/g, function(match) { 32 switch(match) { 33 case 'VIIII': 34 return "IX"; 35 case 'LXXXX': 36 return "XC"; 37 case 'DCCCC': 38 return "CM"; 39 case 'IIII': 40 return "IV"; 41 case 'XXXX': 42 return "XL"; 43 case 'CCCC': 44 return "CD"; 45 } 46 }); 47 return newStr; 48 }
測試部分數字:
console.log(convert(3999)); // MMMCMXCIX console.log(convert(3444)); // MMMCDXLIV console.log(convert(1234)); // MCCXXXIV console.log(convert(83)); // LXXXIII console.log(convert(123)); // CXXIII
至此,基本功能已經實現了。
另外,用for循環測試了前幾千個較小的數,都是能正常轉換的,較大的數長度會較長,因為沒有對5000,10000等數進行處理。