Convert a number into a Roman Numeral in javaScrip

2020-01-24 03:23发布

问题:

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

回答1:

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;
}


回答2:

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



回答3:

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;
}


回答4:

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]);
    }
  }
}


回答5:

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;
};


回答6:

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">



回答7:

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



回答8:

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.



回答9:

I know this is a dated question but I have the shortest solution of the ones listed here and thought I would share since I think its easier to understand.

This version does not require any hard coded logic for edge cases such as 4(IV),9(IX),40(XL),900(CM), etc. as the others do. This also means it can handle larger numbers greater than the maximum roman scale could (3999). For example if "T" became a new symbol you could add it to the beginning of the romanLookup object and it would keep the same algorithmic affect; or course assuming the "no more than 3 of the same symbol in a row" rule applies.

I have tested this against a data set from 1-3999 and it works flawlessly.

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);


回答10:

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 overlines so, you would need to use some trick to represent that, maybe a DIV with border-top, or some background image with those two overlines... 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;
}


回答11:

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;
}


回答12:

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));


回答13:

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;
}



回答14:

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>



回答15:

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



回答16:

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>



回答17:

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;
}


回答18:

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;
}


回答19:

Loops may be more elegant but I find them hard to read. Came up with a more or less hard coded version that's easy on the eyes. As long as you understand the very first line, the rest is a no-brainer.

function romanNumeralGenerator (int) {
  let roman = '';

  roman +=  'M'.repeat(int / 1000);  int %= 1000; 
  roman += 'CM'.repeat(int / 900);   int %= 900; 
  roman +=  'D'.repeat(int / 500);   int %= 500;  
  roman += 'CD'.repeat(int / 400);   int %= 400;
  roman +=  'C'.repeat(int / 100);   int %= 100;
  roman += 'XC'.repeat(int / 90);    int %= 90;
  roman +=  'L'.repeat(int / 50);    int %= 50;
  roman += 'XL'.repeat(int / 40);    int %= 40;
  roman +=  'X'.repeat(int / 10);    int %= 10;
  roman += 'IX'.repeat(int / 9);     int %= 9;
  roman +=  'V'.repeat(int / 5);     int %= 5;
  roman += 'IV'.repeat(int / 4);     int %= 4;
  roman +=  'I'.repeat(int);

  return roman;
}


回答20:

/*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


回答21:

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]);        
        }
    }
}


回答22:

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>



回答23:

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;
}


回答24:

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);


回答25:

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;
}


回答26:

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);


回答27:

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;
}


回答28:

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);


回答29:

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;
}


回答30:

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. -->