在javaScript中将数字转换为罗马数字

如何将整数转换成罗马数字 ?

function romanNumeralGenerator (int) { } 

例如,请参阅以下示例input和输出:

 1 = "I" 5 = "V" 10 = "X" 20 = "XX" 3999 = "MMMCMXCIX" 

注意:只支持1到3999之间的数字

在这个博客上有一个很好的使用谷歌:

http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter

 function romanize (num) { if (!+num) return NaN; var digits = String(+num).split(""), key = ["","C","CC","CCC","CD","D","DC","DCC","DCCC","CM", "","X","XX","XXX","XL","L","LX","LXX","LXXX","XC", "","I","II","III","IV","V","VI","VII","VIII","IX"], roman = "", i = 3; while (i--) roman = (key[+digits.pop() + (i * 10)] || "") + roman; return Array(+digits.join("") + 1).join("M") + roman; } 
 function romanize(num) { var lookup = {M:1000,CM:900,D:500,CD:400,C:100,XC:90,L:50,XL:40,X:10,IX:9,V:5,IV:4,I:1},roman = '',i; for ( i in lookup ) { while ( num >= lookup[i] ) { roman += i; num -= lookup[i]; } } return roman; } 

转载自2008年的评论: http : //blog.stevenlevithan.com/archives/javascript-roman-numeral-converter

查看演示

我不明白为什么每个人的解决scheme是这么长,并使用多个for循环。

 function convertToRoman(num) { var roman = {"M" :1000, "CM":900, "D":500, "CD":400, "C":100, "XC":90, "L":50, "XL":40, "X":10, "IX":9, "V":5, "IV":4, "I":1}; var str = ""; for (var i of Object.keys(roman) ) { var q = Math.floor(num / roman[i]); num -= q * roman[i]; str += i.repeat(q); } return str; } 

我已经开发了下面的recursion解决scheme。 该函数返回一个字母,然后调用自己返回下一个字母。 直到传递给函数的数字为0 ,这意味着所有的字母都被find了,我们可以退出recursion。

 var romanMatrix = [ [1000, 'M'], [900, 'CM'], [500, 'D'], [400, 'CD'], [100, 'C'], [90, 'XC'], [50, 'L'], [40, 'XL'], [10, 'X'], [9, 'IX'], [5, 'V'], [4, 'IV'], [1, 'I'] ]; function convertToRoman(num) { if (num === 0) { return ''; } for (var i = 0; i < romanMatrix.length; i++) { if (num >= romanMatrix[i][0]) { return romanMatrix[i][1] + convertToRoman(num - romanMatrix[i][0]); } } } 

这些函数将任何正整数转换为其等效的罗马数字string; 和任何罗马数字的数量。

数字到罗马数字:

 Number.prototype.toRoman= function () { var num = Math.floor(this), val, s= '', i= 0, v = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1], r = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I']; function toBigRoman(n) { var ret = '', n1 = '', rem = n; while (rem > 1000) { var prefix = '', suffix = '', n = rem, s = '' + rem, magnitude = 1; while (n > 1000) { n /= 1000; magnitude *= 1000; prefix += '('; suffix += ')'; } n1 = Math.floor(n); rem = s - (n1 * magnitude); ret += prefix + n1.toRoman() + suffix; } return ret + rem.toRoman(); } if (this - num || num < 1) num = 0; if (num > 3999) return toBigRoman(num); while (num) { val = v[i]; while (num >= val) { num -= val; s += r[i]; } ++i; } return s; }; 

数字罗马数字string:

 Number.fromRoman = function (roman, accept) { var s = roman.toUpperCase().replace(/ +/g, ''), L = s.length, sum = 0, i = 0, next, val, R = { M: 1000, D: 500, C: 100, L: 50, X: 10, V: 5, I: 1 }; function fromBigRoman(rn) { var n = 0, x, n1, S, rx =/(\(*)([MDCLXVI]+)/g; while ((S = rx.exec(rn)) != null) { x = S[1].length; n1 = Number.fromRoman(S[2]) if (isNaN(n1)) return NaN; if (x) n1 *= Math.pow(1000, x); n += n1; } return n; } if (/^[MDCLXVI)(]+$/.test(s)) { if (s.indexOf('(') == 0) return fromBigRoman(s); while (i < L) { val = R[s.charAt(i++)]; next = R[s.charAt(i)] || 0; if (next - val > 0) val *= -1; sum += val; } if (accept || sum.toRoman() === s) return sum; } return NaN; }; 

我知道这是一个古老的问题,但我为这个解决scheme感到非常自豪:)它只处理小于1000的数字,但可以很容易地扩大到包括大,你需要通过添加到'numerCodes'二维数组。

 var numeralCodes = [["","I","II","III","IV","V","VI","VII","VIII","IX"], // Ones ["","X","XX","XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"], // Tens ["","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"]]; // Hundreds function convert(num) { var numeral = ""; var digits = num.toString().split('').reverse(); for (var i=0; i < digits.length; i++){ numeral = numeralCodes[i][parseInt(digits[i])] + numeral; } return numeral; } 
 <input id="text-input" type="text"> <button id="convert-button" onClick="var n = parseInt(document.getElementById('text-input').value);document.getElementById('text-output').value = convert(n);">Convert!</button> <input id="text-output" style="display:block" type="text"> 

JavaScript的

 function romanize (num) { if (!+num) return false; var digits = String(+num).split(""), key = ["","C","CC","CCC","CD","D","DC","DCC","DCCC","CM", "","X","XX","XXX","XL","L","LX","LXX","LXXX","XC", "","I","II","III","IV","V","VI","VII","VIII","IX"], roman = "", i = 3; while (i--) roman = (key[+digits.pop() + (i * 10)] || "") + roman; return Array(+digits.join("") + 1).join("M") + roman; } 

许多其他build议可以在http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter

这个函数将把任何小于3,999,999的数字转换成罗马数字。 请注意,大于3999的数字将位于text-decoration设置为overline的标签内,当数字大于3999时,这将添加作为overline的正确表示的覆盖。

四百万(四百万)将是四,两个overline s,所以,你需要用一些技巧来表示,也许是border-topDIV ,或者一些背景图像与这两个overline s …每个overline代表x1000。

 function convert(num){ num = parseInt(num); if (num > 3999999) { alert('Number is too big!'); return false; } if (num < 1) { alert('Number is too small!'); return false; } var result = '', ref = ['M','CM','D','CD','C','XC','L','XL','X','IX','V','IV','I'], xis = [1000,900,500,400,100,90,50,40,10,9,5,4,1]; if (num <= 3999999 && num >= 4000) { num += ''; // need to convert to string for .substring() result = '<label style="text-decoration: overline;">'+convert(num.substring(0,num.length-3))+'</label>'; num = num.substring(num.length-3); } for (x = 0; x < ref.length; x++){ while(num >= xis[x]){ result += ref[x]; num -= xis[x]; } } return result; } 

在testing了这篇文章中的一些实现之后,为了更快的执行,我创build了一个新的实现。 时间执行与其他人相比真的很低,但显然代码是丑陋的:)。 使用具有所有可能性的索引数组可能会更快。 以防万一它有助于某人。

 function concatNumLetters(letter, num) { var text = ""; for(var i=0; i<num; i++){ text += letter; } return text; } function arabicToRomanNumber(arabic) { arabic = parseInt(arabic); var roman = ""; if (arabic >= 1000) { var thousands = ~~(arabic / 1000); roman = concatNumLetters("M", thousands); arabic -= thousands * 1000; } if (arabic >= 900) { roman += "CM"; arabic -= 900; } if (arabic >= 500) { roman += "D"; arabic -= 500; } if (arabic >= 400) { roman += "CD"; arabic -= 400; } if (arabic >= 100) { var hundreds = ~~(arabic / 100); roman += concatNumLetters("C", hundreds); arabic -= hundreds * 100; } if (arabic >= 90) { roman += "XC"; arabic -= 90; } if (arabic >= 50) { roman += "L"; arabic -= 50; } if (arabic >= 40) { roman += "XL"; arabic -= 40; } if (arabic >= 10) { var dozens = ~~(arabic / 10); roman += concatNumLetters("X", dozens); arabic -= dozens * 10; } if (arabic >= 9) { roman += "IX"; arabic -= 9; } if (arabic >= 5) { roman += "V"; arabic -= 5; } if (arabic >= 4) { roman += "IV"; arabic -= 4; } if (arabic >= 1) { roman += concatNumLetters("I", arabic); } return roman; } 

我创build了两个双胞胎arrays,一个是阿拉伯数字,另一个是罗马字符。

 function convert(num) { var result = ''; var rom = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I']; var ara = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]; 

如果你想用更多的符号来转换一个大数字,也许这个algorithm可以帮助。

符号的唯一前提是必须是奇数,遵循相同的规则(1,5,10,50,100 …. 10 ^(N)/ 2,10 ^(N))。

 var rnumbers = ["I","V","X","L","C","D","M"]; rnumbers = rnumbers.concat(["V","X","L","C","D","M"].map(function(n) {return '<span style="border-top:1px solid black; padding:1px;">'+n+'</span> '})); rnumbers = rnumbers.concat(["V","X","L","C","D","M"].map(function(n) {return '<span style="border:1px solid black; border-bottom:1px none black; padding:1px;">'+n+'</span> '})); rnumbers = rnumbers.concat(["V","X","L","C","D","M"].map(function(n) {return '<span style="border-top:3px double black; padding:1px;">'+n+'</span> '})); String.prototype.repeat = function( num ) { return new Array( num + 1 ).join( this ); }; function toRoman(n) { if(!n) return ""; var strn = new String(n); var strnlength = strn.length; var ret = ""; for(var i = 0 ; i < strnlength; i++) { var index = strnlength*2 -2 - i*2; var str; var m = +strn[i]; if(index > rnumbers.length -1) { str = rnumbers[rnumbers.length-1].repeat(m*Math.pow(10,Math.ceil((index-rnumbers.length)/2))); }else { str = rnumbers[index].repeat(m); if (rnumbers.length >= index + 2) { var rnregexp = rnumbers[index] .split("(").join('\\(') .split(")").join('\\)'); str = str.replace(new RegExp('(' + rnregexp + '){9}'), rnumbers[index] + rnumbers[index + 2]) .replace(new RegExp('(' + rnregexp + '){5}'), rnumbers[index + 1]) .replace(new RegExp('(' + rnregexp + '){4}'), rnumbers[index] + rnumbers[index + 1]) } } ret +=str; } return ret; } 
 <input type="text" value="" onkeyup="document.getElementById('result').innerHTML = toRoman(this.value)"/> <br/><br/> <div id="result"></div> 
 function convertToRoman(num) { var romans = { 1000: 'M', 900: 'CM', 500: 'D', 400: 'CD', 100: 'C', 90: 'XC', 50: 'L', 40: 'XL', 10: 'X', 9: 'IX', 5: 'V', 4: 'IV', 1: 'I' }; var popped, rem, roman = '', keys = Object.keys(romans); while (num > 0) { popped = keys.pop(); m = Math.floor(num / popped); num = num % popped; console.log('popped:', popped, ' m:', m, ' num:', num, ' roman:', roman); while (m-- > 0) { roman += romans[popped]; } while (num / popped === 0) { popped = keys.pop(); delete romans[popped]; } } return roman; } var result = convertToRoman(3999); console.log(result); document.getElementById('roman').innerHTML = 'Roman: ' + result; 
 p { color: darkblue; } 
 <p>Decimal: 3999</p> <p id="roman">Roman:</p> 

我只是在freecodecamp做了这个。 它可以很容易地扩大。

 function convertToRoman(num) { var roman =""; var values = [1000,900,500,400,100,90,50,40,10,9,5,4,1]; var literals = ["M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"]; for(i=0;i<values.length;i++){ if(num>=values[i]){ if(5<=num && num<=8) num -= 5; else if(1<=num && num<=3) num -= 1; else num -= values[i]; roman += literals[i]; i--; } } return roman; } 

我个人认为,最简单的方式(不是最快的)是recursion。

 function convert(num) { if(num < 1){ return "";} if(num >= 40){ return "XL" + convert(num - 40);} if(num >= 10){ return "X" + convert(num - 10);} if(num >= 9){ return "IX" + convert(num - 9);} if(num >= 5){ return "V" + convert(num - 5);} if(num >= 4){ return "IV" + convert(num - 4);} if(num >= 1){ return "I" + convert(num - 1);} } console.log(convert(39)); //Output: XXXIX 

这只会支持数字1-40 ,但可以通过遵循这个模式来轻松扩展。

 /*my beginner-nooby solution for numbers 1-999 :)*/ function convert(num) { var RomNumDig = [['','I','II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX'],['X','XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC'], ['C','CC','CCC','CD','D','DC','DCC','DCCC','CM']]; var lastDig = num%10; var ourNumb1 = RomNumDig[0][lastDig]||''; if(num>=10) { var decNum = (num - lastDig)/10; if(decNum>9)decNum%=10; var ourNumb2 = RomNumDig[1][decNum-1]||'';} if(num>=100) { var hundNum = ((num-num%100)/100); var ourNumb3 = RomNumDig[2][hundNum-1]||'';} return ourNumb3+ourNumb2+ourNumb1; } console.log(convert(950));//CML /*2nd my beginner-nooby solution for numbers 1-10, but it can be easy transformed for larger numbers :)*/ function convert(num) { var ourNumb = ''; var romNumDig = ['I','IV','V','IX','X']; var decNum = [1,4,5,9,10]; for (var i=decNum.length-1; i>0; i--) { while(num>=decNum[i]) { ourNumb += romNumDig[i]; num -= decNum[i]; } } return ourNumb; } console.log(convert(9));//IX 
 function toRoman(n) { var decimals = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]; var roman = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I']; for (var i = 0; i < decimals.length; i++) { if(n < 1) return ""; if(n >= decimals[i]) { return roman[i] + toRoman(n - decimals[i]); } } } 

此function在每个数字中的不同字符集上工作。 要添加另一个数字,请将罗马数字串添加到1位,5位以及接下来的1位。 这很好,因为你只需要知道下一组使用的字符就可以更新它。

 function toRoman(n){ var d=0,o="",v,k="IVXLCDM".split(""); while(n!=0){ v=n%10,x=k[d],y=k[d+1],z=k[d+2]; o=["",x,x+x,x+x+x,x+y,y,y+x,y+x+x,y+x+x+x,x+z][v]+o; n=(nv)/10,d+=2; } return o } var out = ""; for (var i = 0; i < 100; i++) { out += toRoman(i) + "\n"; } document.getElementById("output").innerHTML = out; 
 <pre id="output"></pre> 

如果这个数字在HTMLElement (比如span)中,我们推荐添加HTML属性 data-format

 <p>Phase <span data-format="roman">4 </span> Sales</p> 

注意:这不是一个html标准。 在jsfiddle的html部分中向下滚动时,使用的Javascript代码是可见的。

DEMO

这是我第一次被困在freecodecamp上。 我在这里通过一些解决scheme来阅读,并惊讶于他们是如何不同。 这是什么最终为我工作。

 function convertToRoman(num) { var roman = ""; var lookupObj = { 1000:"M", 900:"CM", 500:"D", 400:"CD", 100:"C", 90:"XC", 50:"L", 40:"XL", 10:"X", 9:"IX", 4:"IV", 5:"V", 1:"I", }; var arrayLen = Object.keys(lookupObj).length; while(num>0){ for (i=arrayLen-1 ; i>=0 ; i--){ if(num >= Object.keys(lookupObj)[i]){ roman = roman + lookupObj[Object.keys(lookupObj)[i]]; num = num - Object.keys(lookupObj)[i]; break; } } } return roman; } convertToRoman(1231); 
 function convertToRoman(num) { var romNumerals = [["M", 1000], ["CM", 900], ["D", 500], ["CD", 400], ["C", 100], ["XC", 90], ["L", 50], ["XL", 40], ["X", 10], ["IX", 9], ["V", 5], ["IV", 4], ["I", 1]]; var runningTotal = 0; var roman = ""; for (var i = 0; i < romNumerals.length; i++) { while (runningTotal + romNumerals[i][1] <= num) { runningTotal += romNumerals[i][1]; roman += romNumerals[i][0]; } } return roman; } 
 function convertToRoman(num) { var roNumerals = { M: Math.floor(num / 1000), CM: Math.floor(num % 1000 / 900), D: Math.floor(num % 1000 % 900 / 500), CD: Math.floor(num % 1000 % 900 % 500 / 400), C: Math.floor(num % 1000 % 900 % 500 % 400 / 100), XC: Math.floor(num % 1000 % 900 % 500 % 400 % 100 / 90), L: Math.floor(num % 1000 % 900 % 500 % 400 % 100 % 90 / 50), XL: Math.floor(num % 1000 % 900 % 500 % 400 % 100 % 90 % 50 / 40), X: Math.floor(num % 1000 % 900 % 500 % 400 % 100 % 90 % 50 % 40 / 10), IX: Math.floor(num % 1000 % 900 % 500 % 400 % 100 % 90 % 50 % 40 % 10 / 9), V: Math.floor(num % 1000 % 900 % 500 % 400 % 100 % 90 % 50 % 40 % 10 % 9 / 5), IV: Math.floor(num % 1000 % 900 % 500 % 400 % 100 % 90 % 50 % 40 % 10 % 9 % 5 / 4), I: Math.floor(num % 1000 % 900 % 500 % 400 % 100 % 90 % 50 % 40 % 10 % 9 % 5 % 4 / 1) }; var roNuStr = ""; for (var prop in roNumerals) { for (i = 0; i < roNumerals[prop]; i++) { roNuStr += prop; } } return roNuStr; } convertToRoman(9); 
 function convertToRoman (num) { var v = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]; var r = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I']; var s = ""; for(i = 0; i < v.length; i++) { value = parseInt(num/v[i]); for(j = 0; j < value; j++) { s += r[i]; } num = num%v[i]; } return s; } 

仍然感到自豪:)它在1-3999之间工作。

 var converterArray = [{"1":["I","IV","V","IX"], "2":["X","XL","L","XC"], "3":["C","CD","D","CM"], "4":["M"]} ]; function convertToRoman(num) { var romanNumeral = []; var numArr = num.toString().split(''); var numLength = numArr.length; for (var i = 0; i<numArr.length; i++) { if (numArr[i] < 4) { for (var j = 0; j<numArr[i]; j++) { romanNumeral.push(converterArray[0][numLength][0]); } } else if (numArr[i] < 5) { for (var j = 3; j<numArr[i]; j++) { romanNumeral.push(converterArray[0][numLength][1]); } } else if (numArr[i] < 9) { romanNumeral.push(converterArray[0][numLength][2]); for (var j = 5; j<numArr[i]; j++) { romanNumeral.push(converterArray[0][numLength][0]); } } else if (numArr[i] < 10) { for (var j = 8; j<numArr[i]; j++) { romanNumeral.push(converterArray[0][numLength][3]); } } numLength--; } return romanNumeral.join(''); } convertToRoman(9); 

我的解决scheme将数字分割为一个string数组,将每个元素的相对于数组长度的位置添加零,将新的string转换为零,然后将它们连接在一起。 这将只适用于数字高达3999:

 function convertToRoman(num){ var rnumerals = { 1 : 'I', 2 : 'II', 3 : 'III', 4 : 'IV', 5 : 'V', 6 : 'VI', 7 : 'VII', 8 : 'VIII', 9 : 'IX', 10 : 'X', 20 : 'XX', 30 : 'XXX', 40 : 'XL', 50 : 'L', 60 : 'LX', 70 : 'LXX', 80 : 'LXXX', 90 : 'XC', 100 : 'C', 200 : 'CC', 300 : 'CCC', 400 : 'CD', 500 : 'D', 600 : 'DC', 700 : 'DCC', 800 : 'DCCC', 900 : 'CM', 1000: 'M', 2000: 'MM', 3000: 'MMM'}; var zeros, romNum; var arr = num.toString().split(""); var romArr = []; for(var i=0; i < arr.length; i++){ zeros = "0".repeat((arr.length - i - 1)); arr[i] = arr[i].concat(zeros); romArr.push(rnumerals[(arr[i])]); } romNum = romArr.join(''); return romNum; } 
 var romanNumerals = [ ['M', 1000],['CM', 900],['D', 500],['CD', 400],['C', 100],['XC', 90],['L', 50],['XL', 40],['X', 10],['IX', 9],['V', 5],['IV', 4],['I', 1]]; RomanNumerals = { romerate: function(foo) { var bar = ''; romanNumerals.forEach(function(buzz) { while (foo >= buzz[1]) { bar += buzz[0]; foo -= buzz[1]; } }); return bar; }, numerate: function(x) { var y = 0; romanNumerals.forEach(function(z) { while (x.substr(0, z[0].length) == z[0]) { x = x.substr(z[0].length); y += z[1]; } }); return y; } }; 

这适用于所有只需要罗马数字M及以下的数字。

 function convert(num) { var code = [ [1000, "M"], [900, "CM"], [800, "DCCC"], [700, "DCC"], [600, "DC"], [500, "D"], [400, "CD"], [300, "CCC"], [200, "CC"], [100, "C"], [90, "XC"], [80, "LXXX"], [70, "LXX"], [60, "LX"], [50, "L"], [40, "XL"], [30, "XXX"], [20, "XX"], [10, "X"], [9, "IX"], [8, "VIII"], [7, "VII"], [6, "VI"], [5, "V"], [4, "IV"], [3, "III"], [2, "II"], [1, "I"], ]; var rom = ""; for(var i=0; i<code.length; i++) { while(num >= code[i][0]) { rom += code[i][1]; num -= code[i][0]; } } return rom; } 

我知道这是一个过时的问题,但我有这里列出的最短的解决scheme,并认为我会分享,因为我认为它更容易理解。

这个版本不需要像4(IV),9(IX),40(XL),900(CM)等其他边界情况的硬编码逻辑。 这也意味着,假设“不超过3排”规则适用,它理论上可以处理大于3999的大数。

我已经testing了这个对1-3999,它的工作完美无瑕。

 function convertToRoman(num) { //create key:value pairs var romanLookup = {M:1000, D:500, C:100, L:50, X:10, V:5, I:1}; var roman = []; var romanKeys = Object.keys(romanLookup); var curValue; var index; var count = 1; for(var numeral in romanLookup){ curValue = romanLookup[numeral]; index = romanKeys.indexOf(numeral); while(num >= curValue){ if(count < 4){ //push up to 3 of the same numeral roman.push(numeral); } else { //else we had to push four, so we need to convert the numerals //to the next highest denomination "coloring-up in poker speak" //Note: We need to check previous index because it might be part of the current number. //Example:(9) would attempt (VIIII) so we would need to remove the V as well as the I's //otherwise removing just the last three III would be incorrect, because the swap //would give us (VIX) instead of the correct answer (IX) if(roman.indexOf(romanKeys[index - 1]) > -1){ //remove the previous numeral we worked with //and everything after it since we will replace them roman.splice(roman.indexOf(romanKeys[index - 1])); //push the current numeral and the one that appeared two iterations ago; //think (IX) where we skip (V) roman.push(romanKeys[index], romanKeys[index - 2]); } else { //else Example:(4) would attemt (IIII) so remove three I's and replace with a V //to get the correct answer of (IV) //remove the last 3 numerals which are all the same roman.splice(-3); //push the current numeral and the one that appeared right before it; think (IV) roman.push(romanKeys[index], romanKeys[index - 1]); } } //reduce our number by the value we already converted to a numeral num -= curValue; count++; } count = 1; } return roman.join(""); } convertToRoman(36); 

好吧,我并不是唯一一个在FreeCodeCamp上遇到这个挑战的人。 但是我想无论如何都要和你分享我的代码。 这是相当高效的,比顶级解决scheme快了近10%(我没有testing过所有其他的,我猜我的速度不是最快的)。 但是我认为它很简单易懂:

 function convertToRoman(num) { // Some error checking first if (+num > 9999) { console.error('Error (fn convertToRoman(num)): Can\'t convert numbers greater than 9999. You provided: ' + num); return false; } if (!+num) { console.error('Error (fn convertToRoman(num)): \'num\' must be a number or number in a string. You provided: ' + num); return false; } // Convert the number into // an array of the numbers var arr = String(+num).split('').map((el) => +el ); // Keys to the roman numbers var keys = { 1: ['', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX'], 2: ['', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC'], 3: ['', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM'], 4: ['', 'M', 'MM', 'MMM', 'MMMM', 'MMMMM', 'MMMMMM', 'MMMMMMM', 'MMMMMMMM', 'MMMMMMMMM'], }; // Variables to help building the roman string var i = arr.length; var roman = ''; // Iterate over each number in the array and // build the string with the corresponding // roman numeral arr.forEach(function (el) { roman += keys[i][el]; i--; }); // Return the string return roman; } 

这似乎是一个限制,它只能把数字转换成9 999.但事实是,从10 000以上的一行应提供文字上方。 而我还没有解决。

希望这会帮助你。

 function convertToRoman(num) { var search = { "0":["I","II","III","IV","V","VI","VII","VIII","IX"], "1":["X","XX","XXX","XL","L","LX","LXX","LXXX","XC"], "2":["C","CC","CCC","CD","D","DC","DCC","DCCC","CM"], "3":["M","MM","MMM","MV^","V^","V^M","V^MM","V^MMM","MX^"], }; var numArr = num.toString().split("").reverse(); var romanReturn = []; for(var i=0; i<numArr.length; i++){ romanReturn.unshift(search[i][numArr[i]-1]); } return romanReturn.join(""); } 

这是我的解决scheme,我不太确定它的performance如何。

 function convertToRoman(num) { var uni = ["","I","II","III","IV","V","VI","VII","VIII","IX"]; var dec = ["","X","XX","XXX","XL","L","LX","LXX","LXXX","XC"]; var cen = ["","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"]; var mil = ["","M","MM","MMM","MMMM","MMMMM","MMMMMM","MMMMMMM","MMMMMMMM","MMMMMMMMMM"]; var res =[]; if(num/1000 > 0) { res = res.concat(mil[Math.floor(num/1000)]); } if(num/100 > 0) { res = res.concat(cen[Math.floor((num%1000)/100)]); } if(num/10 >0) { res = res.concat(dec[Math.floor(((num%1000)%100)/10)]); } res=res.concat(uni[Math.floor(((num%1000)%100)%10)]); return res.join(''); }