How can I convert integers into roman numerals?
function romanNumeralGenerator (int) {
}
For example, see the following sample inputs and outputs:
1 = "I"
5 = "V"
10 = "X"
20 = "XX"
3999 = "MMMCMXCIX"
Caveat: Only support numbers between 1 and 3999
There is a nice one here on this blog I found using google:
http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter
function romanize (num) {
if (isNaN(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;
}
Reposted from a 2008 comment located at: http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter
VIEW DEMO
I don't understand why everyones solution is so long and uses multiple for loops.
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;
}
These functions convert any positive whole number to its equivalent Roman Numeral string; and any Roman Numeral to its number.
Number to Roman Numeral:
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;
};
Roman Numeral string to Number:
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;
};
I've developed the recursive solution below. The function returns one letter and then calls itself to return the next letter. It does it until the number passed to the function is 0
which means that all letters have been found and we can exit the 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]);
}
}
}
I know this is an old question but I'm pretty proud of this solution :) It only handles numbers less than 1000 but could easily be expanded to include however large you'd need by adding on to the 'numeralCodes' 2D array.
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;
}
many other suggestions can be found at http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter
I personally think the neatest way (not by any means the fastest) is with 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
This will only support numbers 1-40, but it can easily be extended by following the pattern.
This function will convert any number smaller than 3,999,999 to roman. Notice that numbers bigger than 3999 will be inside a label with text-decoration
set to overline
, this will add the overline
that is the correct representation for x1000 when the number is bigger than 3999.
Four million (4,000,000) would be IV with two overline
s so, you would need to use some trick to represent that, maybe a DIV
with border-top
, or some background image with those two overline
s... Each overline
represents 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;
}
After testing some of the implementations in this post, I have created a new optimized one in order to execute faster. The time execution is really low comparing with the others, but obviously the code is uglier :). It could be even faster with an indexed array with all the posibilities. Just in case it helps someone.
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;
}
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 result = '';
for (var key in roman) {
if (num == roman[key]) {
return result +=key;
}
var check = num > roman[key];
if(check) {
result = result + key.repeat(parseInt(num/roman[key]));
num = num%roman[key];
}
}
return result;
}
console.log(convertToRoman(36));
I created two twin arrays one with arabic numbers the other with the roman characters.
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];
Then I added a cycle which scan the roman elements, adding the biggest still comprised in NUM to RESULT, then we decrease NUM of the same amount.
It is like we map a part of NUM in roman numbers and then we decrease it of the same amount.
for (var x = 0; x < rom.length; x++) {
while (num >= ara[x]) {
result += rom[x];
num -= ara[x];
}
}
return result;
}
If you want to convert a big number with more symbols, maybe this algo could help.
The only premise for symbols is that must be odd and follow the same rule (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>
IF this number in HTMLElement (such as span), we recommend to Add HTML attribute data-format
:
<p>Phase <span data-format="roman">4 </span> Sales</p>
Note : This is not a html standard. Javascript code used is visible once you scroll down in the html section on jsfiddle.
DEMO
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>
I just made this at freecodecamp. It can easily be expanded.
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;
}
Here's a regular expression solution:
function deromanize(roman) {
var r = 0;
// regular expressions to check if valid Roman Number.
if (!/^M*(?:D?C{0,3}|C[MD])(?:L?X{0,3}|X[CL])(?:V?I{0,3}|I[XV])$/.test(roman))
throw new Error('Invalid Roman Numeral.');
roman.replace(/[MDLV]|C[MD]?|X[CL]?|I[XV]?/g, function(i) {
r += {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}[i];
});
return r;
}
/*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]);
}
}
}
This function works on the the different character sets in each digit. To add another digit add the roman numeral string the 1 place, 5 place and next 1 place. This is nice because you update it with only knowing the next set of characters used.
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=(n-v)/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>
This works for all numbers only in need of roman numerals M and below.
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;
}
This is the first time I really got stuck on freecodecamp. I perused through some solutions here and was amazed at how different they all were. Here is what ended up working for me.
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;
}
Still proud of it :) It works between 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);
My solution breaks the number in to an array of strings, adds zeros to each element based on its position relative to the length of the array, converts the new strings with zeros to roman numerals, and then joins them back together. This will only work with numbers up to 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;
}
If it is just for display purpose, use the standard HTML with a bit of JS for the value (if needed) and CSS to make it inline:
ol.roman-lowercase,
ol.roman-uppercase {
display: inline-flex;
margin: 0;
padding: 0;
}
ol.roman-lowercase {
list-style: lower-roman inside;
}
ol.roman-uppercase {
list-style: upper-roman inside;
}
<ol class="roman-lowercase"><li value="4"></li></ol> <!-- iv. -->
<ol class="roman-uppercase"><li value="142"></li></ol> <!-- CXLII. -->
function convertToRoman(num) {
var arr = [];
for (var i = 0; i < num.toString().length; i++) {
arr.push(Number(num.toString().substr(i, 1)));
}
var romanArr = [
["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"],
["M"]
];
var roman = arr.reverse().map(function (val, i) {
if (val === 0) {
return "";
}
if (i === 3) {
var r = "";
for (var j = 0; j < val; j++) {
r += romanArr[i][0];
}
return r;
} else {
return romanArr[i][val - 1];
}
});
console.log(roman.reverse().join(""));
return roman.join("");
}
convertToRoman(10);
I feel my solution is much more readable and easy to understand.
var intToRoman = function(num) {
let symbolMap = ['I','V','X','L','C','D','M','P','Q'];
if (num < 1 || num > 9999) {
return null;
}
let i = 0;
let result = '';
while (num) {
let digit = num % 10;
num = parseInt(num / 10);
switch (digit) {
case 1: result = symbolMap[i] + result;
break;
case 2: result = symbolMap[i] + symbolMap[i] + result;
break;
case 3: result = symbolMap[i] + symbolMap[i] + symbolMap[i] + result;
break;
case 4: result = symbolMap[i] + symbolMap[i+1] + result;
break;
case 5: result = symbolMap[i+1] + result;
break;
case 6: result = symbolMap[i+1] + symbolMap[i] + result;
break;
case 7: result = symbolMap[i+1] + symbolMap[i] + symbolMap[i] + result;
break;
case 8: result = symbolMap[i+1] + symbolMap[i] + symbolMap[i] + symbolMap[i] + result;
break;
case 9: result = symbolMap[i] + symbolMap[i+2] + result;
break;
}
i += 2;
}
return result;
};
来源:https://stackoverflow.com/questions/9083037/convert-a-number-into-a-roman-numeral-in-javascript