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

sit_id 发布于 2018-12-23 javascript 最后更新 2018-12-23 15:29 149 浏览

如何将整数转换为roman numerals

function romanNumeralGenerator (int) {
}
例如,请参阅以下示例输入和输出:
1 = "I"
5 = "V"
10 = "X"
20 = "XX"
3999 = "MMMCMXCIX"
警告:只支持1到3999之间的数字
已邀请:

gquia

赞同来自:

这是我的“功能性”解决方案。

var numerals = ["I","V","X","L","C","D","M"],
      number = 1453,
      digits = Array(~~(Math.log10(number)+1)).fill(number).map((n,i) => Math.trunc(n%Math.pow(10,i+1)/Math.pow(10,i))),  // <- [3,5,4,1]
      result = digits.reduce((p,c,i) => (c === 0 ? ""
                                                 : c < 4 ? numerals[2*i].repeat(c)
                                                         : c === 4 ? numerals[2*i] + numerals[2*i+1]
                                                                   : c < 9 ? numerals[2*i+1] + numerals[2*i].repeat(c-5)
                                                                           : numerals[2*i] + numerals[2*i+2]) + p,"");
console.log(result);

ut_quo

赞同来自:

我只是发布了一个我转换为罗马的函数,我希望你喜欢它

function converter(numToConv) {
var numToRom = [];
var numToRome = "";
var R = [['M',1000], ['D',500], ['C',100], ['L',50], ['X',10], ['V',5], ['I',1]];
while (numToConv > 0) {
    if (numToConv > R[0][1]) {
        if (numToConv < R[0][1] * 5 - R[0][1]) {   
            numToRom.push([R[0][0],"next one goes aftah"]);
            numToConv = Math.abs(numToConv - R[0][1]);
            console.log("Next comes after: " + R[0][0] + " (" + R[0][1] + ")");
            console.log(numToConv);
        } else {
            numToConv = 0;
            break;
        }
    }
    for (var i = 0; i < R.length; i++) {
        if (R[i][1] == numToConv) {
            numToRom.push([R[i][0],"end"]);
            numToConv = Math.abs(numToConv - R[i][1]);
            console.log("End: " + numToConv);
        } else if (i > 0) {
            if ((R[i-1][1] > numToConv) && (R[i][1] < numToConv)) {
                console.log(numToConv + " is between: " + R[i][1]  + " (" + R[i][0] + ") and: " +  R[i - 1][1]  + " (" + R[i - 1][0] + ")");
                var threshold = R[i - 1][1] - Math.pow(10, numToConv.toString().length - 1);
                console.log("threshold: " + threshold + " : " + R[i][1] + " : " + Math.pow(10, numToConv.toString().length - 1));
                if (numToConv  < threshold) {
                    numToRom.push([R[i][0],"next one goes aftah"]);
                    numToConv = Math.abs(numToConv - R[i][1]);
                    console.log("Next comes after: " + R[i][0] + " (" + R[i][1] + ")");
                    console.log(numToConv);
                } else {
                    numToRom.push([R[i-1][0],"next one goes befoah"]);
                    numToConv = Math.abs(numToConv - threshold + Math.pow(10, numToConv.toString().length - 1));
                    console.log("Next comes before: " + R[i-1][0] + " (" + R[i-1][1] + ")");
                    console.log(numToConv);
                }
            }
        }
    }
}
console.log("numToRom: " + numToRom);
for (var i = 0; i < numToRom.length; i++) {
    if (numToRom[i][1] == "next one goes befoah") {
        numToRome += (numToRom[i+1][0] + numToRom[i][0]);
        console.log("numToRome goes befoah: " + numToRome + " i: " + i);
        i++;
    } else {
        numToRome += numToRom[i][0];
        console.log("numToRome goes aftah: " + numToRome + " i: " + i);
    }
}
        console.log("numToRome: " + numToRome);
        return numToRome;
} 带注释的编辑代码:
function converter(numToConv) {
    var numToRom = []; //an array empty, ready to store information about the numbers we will use as we analyse the given number 
    var numToRome = ""; // this is a string to add the Roman letters forming our returning number
    var R = [['M',1000], ['D',500], ['C',100], ['L',50], ['X',10], ['V',5], ['I',1]]; //this array stores the matches with the arabic numbers that we are going to need
    while (numToConv > 0) { //just checking, there is no zero
        if (numToConv > R[0][1]) { //checks if the number is bigger than the bigger number in the array
            if (numToConv < R[0][1] * 5 - R[0][1]) { //checks if it is larger even than 4 times the larger number in the array (just because there is not usually a way to express a number by putting 4 times the same letter i.e there is no "IIII", or "XXXX" etc)
                numToRom.push([R[0][0],"next one goes aftah"]);//here is the information we want to pass, we add the letter we are about to use along with info about the next letter
                numToConv = Math.abs(numToConv - R[0][1]);// and now we are subtracting the value of the letter we are using from the number
                console.log("Next comes after: " + R[0][0] + " (" + R[0][1] + ")");// informing about what we encountering
                console.log(numToConv);//..as well as what's the next number
            } else { //if the number is larger than 4 times the larger number in the array (thus it cannot be expressed)
                numToConv = 0; //then 0 the number (unnecessary but still, no problem doing it)
                break;//and of course, breaking the loop, no need to continue
            }
        }
        for (var i = 0; i < R.length; i++) {//now we are about to search our number for each cell of the array with the roman letters (again and again)
            if (R[i][1] == numToConv) { //if the number is equal to the one in the cell (that means the conversion is over)
                numToRom.push([R[i][0],"end"]); //we pass the information about that cell along with the indication that the conversion has ended
                numToConv = Math.abs(numToConv - R[i][1]);//thai can also be skipped but again there is o harm in keeping it
                console.log("End: " + numToConv);// again informing about what we encountering
            } else if (i > 0) { //just a precaution because we are about to use "i-1" 
                if ((R[i-1][1] > numToConv) && (R[i][1] < numToConv)) {//we find the range in which is the given number (for instance: the number 4 is between 1[I] and 5[V])
                    console.log(numToConv + " is between: " + R[i][1]  + " (" + R[i][0] + ") and: " +  R[i - 1][1]  + " (" + R[i - 1][0] + ")");// once again informing
                    var threshold = R[i - 1][1] - Math.pow(10, numToConv.toString().length - 1);// we create this "threshold" to check if the next number is going before or after this one (difference between 7[VII] and 9[IX]). it is the larger number of our range - 10^[depends on how large is the number we want to convert] (for 999, the threshold is 900, it is smaller 1000 - 10^2)
                    console.log("threshold: " + threshold + " : " + numToConv + " : " + R[i - 1][1] + " : " + R[i][1] + " : " + Math.pow(10, numToConv.toString().length - 1));
                    if (numToConv  < threshold) {//if the number is smaller than the "threshold" (like 199 where its threshold is 400)
                        numToRom.push([R[i][0],"next one goes aftah"]);//then the next number is going after
                        numToConv = Math.abs(numToConv - R[i][1]);//and again, subtract the used value of the number we are converting
                        console.log("Next comes after: " + R[i][0] + " (" + R[i][1] + ")");
                        console.log(numToConv);
                    } else { // now, if the number is larger than the threshold (like 99 where its threshold is 90)
                        numToRom.push([R[i-1][0],"next one goes befoah"]);// then the next number is going before the one we add now
                        numToConv = Math.abs(numToConv - R[i - 1][1]);// again, the subtraction, it was "threshold + Math.pow(10, numToConv.toString().length - 1)" but I changed it to "R[i - 1][1]", same result, less operations
                        console.log("Next comes before: " + R[i-1][0] + " (" + R[i-1][1] + ")");
                        console.log(numToConv);
                    }
                }
            }
        }
    }
    console.log("numToRom: " + numToRom); //now that we have all the info we need about the number, show it to the log (just for a check)
    for (var i = 0; i < numToRom.length; i++) {//..and we start running through that info to create our final number
        if (numToRom[i][1] == "next one goes befoah") {//if our information about the cell tells us that the next letter is going before the current one
            numToRome += (numToRom[i+1][0] + numToRom[i][0]);// we add both to our string (the next one first)
            console.log("numToRome goes befoah: " + numToRome + " i: " + i);
            i++;//and we add an extra '1' to the i, so it will skip the next letter (mind that there won't be more than one letters saying that the next one is going before them in a row
        } else {//if the next one is going after the current one
            numToRome += numToRom[i][0]; //we just add the one we are on to the string and go forth
            console.log("numToRome goes aftah: " + numToRome + " i: " + i);
        }
    }
            console.log("numToRome: " + numToRome);
            return numToRome;//return the string and we are done
}

zet

赞同来自:

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

emagni

赞同来自:

我的解决方案将数字分成一个字符串数组,根据每个元素相对于数组长度的位置为每个元素添加零,将新字符串用零转换为罗马数字,然后将它们连接在一起。这仅适用于最高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;
}

wfuga

赞同来自:

在测试了这篇文章中的一些实现之后,我创建了一个新的优化实现,以便更快地执行。与其他人相比,执行时间非常短,但显然代码更加丑陋:)。 使用具有所有可能性的索引数组可能会更快。 以防它有助于某人。

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

emagni

赞同来自:

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

pporro

赞同来自:

如果你想转换一个带有更多符号的大数字,也许这个算法可能有所帮助。 符号的唯一前提是必须是奇数并遵循相同的规则(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>

kalias

赞同来自:

我创建了两个带有阿拉伯数字的双胞胎阵列,另一个带有罗马字符。

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];
然后我添加了一个扫描罗马元素的循环,将NUM中最大的仍包含在RESULT中,然后我们减少相同数量的NUM。 就像我们用罗马数字映射NUM的一部分然后我们减少相同数量的NUM。
  for (var x = 0; x < rom.length; x++) {
    while (num >= ara[x]) {
      result += rom[x];
      num -= ara[x];
    }
  }
  return result;
}

baut

赞同来自:

我个人认为最好的方式(不是最快的方式)是递归。

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号,但可以通过遵循该模式轻松扩展。

ncum

赞同来自:

这些函数将任何正整数转换为其等效的罗马数字字符串;和任何罗马数字到它的数字。 罗马数字的数字:

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;
};
罗马数字字符串到数字:
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;
};

det

赞同来自:

这适用于仅需要罗马数字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;
}

oillo

赞同来自:

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

qquas

赞同来自:

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("");
}

snihil

赞同来自:

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

bsit

赞同来自:

好吧,似乎我不是唯一一个在FreeCodeCamp上遇到这个挑战的人。但无论如何,我想和你分享我的代码。它性能相当高,比这里的最高投票解决方案快10%(我还没有测试过所有其他解决方案,我猜我的速度不是最快)。但我认为它干净且易于理解:

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以上的一行。而我还没有解决。 希望这会帮助你。

dsit

赞同来自:

仍为此感到自豪:)它工作在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);

znon

赞同来自:

function convertToRoman(int) {
    console.log('Number:', int);
    let roman = [];
    let i, k, replacement;
    let seq = ['I', 'V', 'X', 'L', 'C', 'D', 'M'];
while (int > 999) {
        roman.push('M');
        int -= 1000;
    }
    while (int > 499) {
        roman.push('D');
        int -= 500;
    }
    while (int > 99) {
        roman.push('C');
        int -= 100;
    }
    while (int > 49) {
        roman.push('L');
        int -= 50;
    }
    while (int > 9) {
        roman.push('X');
        int -= 10;
    }
    while (int > 4) {
        roman.push('V');
        int -= 5;
    }
    while (int >= 1) {
        roman.push('I');
        int -= 1;
    }
// Replace recurrences of 4 ('IIII' to 'IV')
    for (i = 0; i < roman.length; i++) {
        if (roman[i] == roman[i + 1] &&
            roman[i] == roman[i + 2] &&
            roman[i] == roman[i + 3]) {
            for (k = 0; k < seq.length; k++) {
                if (roman[i] == seq[k]) {
                    replacement = seq[k + 1];
                }
            }
            roman.splice(i + 1, 3, replacement);
        }
    }
// Converting incorrect recurrences ('VIV' to 'IX')
    for (i = 0; i < roman.length; i++) {
        if (roman[i] == roman[i + 2] && roman[i] != roman[i + 1]) {
            for (k = 0; k < seq.length; k++) {
                if (roman[i] == seq[k]) {
                    replacement = seq[k + 1];
                }
            }
            roman[i + 2] = replacement;
            roman.splice(i, 1);
        }
    }
roman = roman.join('');
    return roman;
}

caut

赞同来自:

我不明白为什么每个人的解决方案都这么长,并且使用多个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;
}

eos_et

赞同来自:

这是我的解决方案:

function convertToRoman(num) { 
    let romanNum = "";
    const strNum = String(num);
    const romans = {
        1: ["I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"], // ones
        2: ["X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"], // tens
        3: ["C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"], // hundreds
        4: ["M", "MM", "MMM"] // thousands
    };
for (let i = 1; i <= strNum.length; i++)
        if (Number(strNum[strNum.length - i]) !== 0)
            romanNum = romans[i][strNum[strNum.length - i] - 1] + romanNum;
return romanNum;
}
它在Chrome 60 - https://jsperf.com/num-to-roman中表现相当不错

rsequi

赞同来自:

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>

ut_et

赞同来自:

此函数会将任何小于3,999,999的数字转换为罗马数字。请注意,大于3999的数字将位于text-decoration设置为overline的标签内,当数字大于3999时,这将添加overline,它是x1000的正确表示形式。 四百万(4,000,000)将是两个overline的IV,因此,您需要使用一些技巧来表示,可能是带有border-topDIV,或带有这两个overlines的一些背景图像...每个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;
}

oqui

赞同来自:

这是一种方法,无需遍历所有不同的罗马数字及其相应的数字。它具有恒定的时间O(1)查找,节省了一点时间复杂度。 它从右到左分解每个整数,因此2,473变为3 + 70 + 400 + 2,000,然后使用romanNumerals哈希表查找相应的罗马数字,并将其附加到结果字符串。它通过在从右向左移动的查找之前向每个整数添加额外的0来实现此目的。此解决方案仅适用于1到3,999之间的数字。

    function integerToRoman(int) {
    if (int < 1 || int > 3999) {
        return -1;
    }
var result = '';
    var intStr = int.toString();
    var romanNumerals = { 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 digit = '';
for (var i = intStr.length - 1; i >= 0; i-- ) {
        if (intStr[i] === '0') {
            digit += '0';
            continue;
        }
        var num = intStr[i] + digit;
        result = romanNumerals[num] + result;
        digit += '0';
    }
return result;
}

zomnis

赞同来自:

这是我第一次陷入freecodecamp。我在这里仔细研究了一些解决方案,并惊讶于它们之间的差异。以下是最终为我工作的内容。

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

xillum

赞同来自:

这是我的解决方案,我不太清楚它的表现如何。

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('');
}

cnon

赞同来自:

在我发现使用谷歌的博客上有一个很好的: 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;
}

tvel

赞同来自:

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;
}
许多其他建议可以在http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter找到

znemo

赞同来自:

我从零开始为freecodecamp挑战写了这个。我希望这会对某人有所帮助。

function convertToRoman(num) {
var nums = [0, 0, 0, 0];
var numsRom = ["", "", "", ""];
var nRom = {
        I: "I",
        V: "V",
        X: "X",
        L: "L",
        C: "C",
        D: "D",
        M: "M"
    };
    /*
    1,
    5,
    10,
    50,
    100,
    500,
    1000
    */
var i;
nums[0] = Math.floor(num / 1000);
    nums[1] = Math.floor((num - nums[0] * 1000) / 100);
    nums[2] = Math.floor((num - nums[0] * 1000 - nums[1] * 100) / 10);
    nums[3] = num - nums[0] * 1000 - nums[1] * 100 - nums[2] * 10;
//1000
    for (i = 0; i < nums[0]; i++) {
        numsRom[0] += nRom.M;
    }
//100
    switch (nums[1]) {
        case 1:
        case 2:
        case 3:
            for (i = 0; i < nums[1]; i++) {
                numsRom[1] += nRom.C;
            }
            break;
        case 4:
            numsRom[1] += nRom.C + nRom.D;
            break;
        case 5:
            numsRom[1] += nRom.D;
            break;
        case 6:
        case 7:
        case 8:
            numsRom[1] += nRom.D;
            for (i = 0; i < nums[1] - 5; i++) {
                numsRom[1] += nRom.C;
            }
            break;
        case 9:
            numsRom[1] += nRom.C + nRom.M;
    }
//10
    switch (nums[2]) {
        case 1:
        case 2:
        case 3:
            for (i = 0; i < nums[2]; i++) {
                numsRom[2] += nRom.X;
            }
            break;
        case 4:
            numsRom[2] += nRom.X + nRom.L;
            break;
        case 5:
            numsRom[2] += nRom.L;
            break;
        case 6:
        case 7:
        case 8:
            numsRom[2] += nRom.L;
            for (i = 0; i < nums[2] - 5; i++) {
                numsRom[2] += nRom.X;
            }
            break;
        case 9:
            numsRom[2] += nRom.X + nRom.C;
    }
//1
    switch (nums[3]) {
        case 1:
        case 2:
        case 3:
            for (i = 0; i < nums[3]; i++) {
                numsRom[3] += nRom.I;
            }
            break;
        case 4:
            numsRom[3] += nRom.I + nRom.V;
            break;
        case 5:
            numsRom[3] += nRom.V;
            break;
        case 6:
        case 7:
        case 8:
            numsRom[3] += nRom.V;
            for (i = 0; i < nums[3] - 5; i++) {
                numsRom[3] += nRom.I;
            }
            break;
        case 9:
            numsRom[2] += nRom.I + nRom.X;
    }
return numsRom.join("");
}
console.log("Number: " + 1234 + " is " + convertToRoman(1234));

tut

赞同来自:

function toRoman(n) {
        var r = '';
        for (var c = 0; c < n.length; c++)
            r += calcDigit(eval(n.charAt(c)), n.length - c - 1);
        return r
    }
function Level(i, v, x) {
    this.i = i;
    this.v = v;
    this.x = x
}
levels = [];
levels[0] = new Level('I','V','X');
levels[1] = new Level('X','L','C');
levels[2] = new Level('C','D','M');
function calcDigit(d, l) {
    if (l > 2) {
        var str = '';
        for (var m = 1; m <= d * Math.pow(10, l - 3); m++)
            str += 'M';
        return str
    } else if (d == 1)
        return levels[l].i;
    else if (d == 2)
        return levels[l].i + levels[l].i;
    else if (d == 3)
        return levels[l].i + levels[l].i + levels[l].i;
    else if (d == 4)
        return levels[l].i + levels[l].v;
    else if (d == 5)
        return levels[l].v;
    else if (d == 6)
        return levels[l].v + levels[l].i;
    else if (d == 7)
        return levels[l].v + levels[l].i + levels[l].i;
    else if (d == 8)
        return levels[l].v + levels[l].i + levels[l].i + levels[l].i;
    else if (d == 9)
        return levels[l].i + levels[l].x;
    else
        return ''
}

est_et

赞同来自:

在此代码中,可以通过向letterTable添加新字母来扩展数字的上限:

letterTable = {
  0:{
    1:'I',
    5:'V',
    10:'X'
  },
  1:{
    1:'X',
    5:'L',
    10:'C'
  },
  2:{
    1:'C',
    5:'D',
    10:'M'
  },
  3:{
    1:'M',
    5:'V', // There should be a dash over this letter
    10:'X' // There should be a dash over this letter
  }, 
  // you can add new level of letters here
};
function romanLetter(i, j){
  romanTable = {
    '0':'',
    '1':letterTable[i][1],
    '2':letterTable[i][1]+letterTable[i][1],
    '3':letterTable[i][1]+letterTable[i][1]+letterTable[i][1],
    '4':letterTable[i][1]+letterTable[i][5],
    '5':letterTable[i][5],
    '6':letterTable[i][5]+letterTable[i][1],
    '7':letterTable[i][5]+letterTable[i][1]+letterTable[i][1],
    '8':letterTable[i][5]+letterTable[i][1]+letterTable[i][1]+letterTable[i][1],
    '9':letterTable[i][1]+letterTable[i][10]
  };
return romanTable[j];
}
function convertToRoman(num) {
numStr = String(num);
  var result = '';
  var level = 0;
for (var i=numStr.length-1; i>-1; i--){
    result = romanLetter(level, numStr[i]) + result;
    level++;
  }
return result;
}

nomnis

赞同来自:

我知道这是一个过时的问题,但我对这里列出的问题有最短的解决方案,并且我认为我会分享,因为我认为它更容易理解。 对于边缘情况,例如4(IV),9(IX),40(XL),900(CM)等,该版本不需要任何硬编码逻辑。这也意味着它可以处理大于3999的大数,假设“连续不超过3”规则适用。 我已经对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);

yet

赞同来自:

虽然我的回答并不像其他人那样有效,但我的重点更多的是不用基数编写硬编码,并允许程序找出其余部分。
例如......
而不是:
number = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1],
numeral = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I']
我用了: base = ['I', 'X', 'C', 'M']; pivot = ['V', 'L', 'D'];

function basicRomanNumerals(num){
let base = ['I', 'X', 'C', 'M'];
let pivot = ['V', 'L', 'D'];
return String(num).split('').reverse().map(function(num, idx){
    let distance = +num - 5;
    let is1AwayFromNext = Math.abs(+num - 10) === 1;
    if(Math.abs(distance)=== 1 || is1AwayFromNext){
        if(is1AwayFromNext){
            return base[idx]+""+base[idx+1];
        }else if ( distance < 0 ){
            return base[idx]+""+pivot[idx];
        }else{
            return pivot[idx]+""+base[idx];
        }
    }else if(distance === 0){
        return pivot[idx];
    }else if(distance > 1){
        return pivot[idx]+""+base[idx].repeat(+num-5);
    }else{
        return base[idx].repeat(+num);
    }
}).reverse().join('');

non_et

赞同来自:

我知道这是一个老问题,但我为这个解决方案感到非常自豪:)它只处理小于1000的数字,但可以通过添加到'numeralCodes'的2D数组轻松扩展到包括你需要的大数。

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

gsint

赞同来自:

我已经开发了下面的递归解决方案。该函数返回一个字母,然后调用自身以返回下一个字母。直到传递给函数的数字为0,这意味着已找到所有字母并且我们可以退出递归。

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

asaepe

赞同来自:

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

VIEW DEMO

hea

赞同来自:

const romanize = num => {
  const romans = {
    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
  };
let roman = '';
for (let key in romans) {
    const times = Math.trunc(num / romans[key]);
    roman += key.repeat(times);
    num -= romans[key] * times;
  }
return roman;
}
console.log(
  romanize(38)
)

xhic

赞同来自:

我刚刚在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;
}

lenim

赞同来自:

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

amodi

赞同来自:

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

gautem

赞同来自:

此功能适用于每个数字中的不同字符集。要添加另一个数字,请将罗马数字字符串添加到1个地方,5个地方和下一个地方。这很好,因为您只需要知道下一组字符就可以更新它。

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>

weos

赞同来自:

我讨厌将所有可能性列入数组(许多人选择解决这个难题)所以我使用另一个函数来完成这项工作。这是我的解决方案:

//a function that convert a single number to roman number, you can choose how to convert it so later you can apply to different part of the number
function romannum(num,rnum1,rnum2,rnum3){
  var result = "";
  if(num >= 1 && num < 4){
    while(num>0){
      result += rnum1;
      num--;
    }
  }
  else if(num > 5 && num < 9){
    result = rnum2;
    while(num>5){
      result += rnum1;
      num--;
    }  
  }
  else if(num == 4){
    result += rnum1 + rnum2;
  }
  else if( num == 5){
    result += rnum2;
  }
  else if( num == 9){
    result += rnum1+ rnum3;
  }
  return result;
}
//the main function
function convertToRoman(num) {
 num = num.toString().split('');
 var length = num.length;
 var x = 0;
 var result =[];
while((length - x) > 0){
   if(length -x === 4){
    result.push(romannum(num[x],"M","",""));
   }
   else if(length -x  === 3){
     result.push(romannum(num[x],"C","D","M"));
   }
   else if(length - x  === 2){
     result.push(romannum(num[x],"X","L","C"));
   }
   else if(length - x === 1){
     result.push(romannum(num[x],"I","V","X"));
   }
   x++;  
 }

est_ut

赞同来自:

我刚刚在freeCodeCamp上完成了这个,我没有看到这个特殊的解决方案。我知道这个解决方案可以通过递归进行优化,但我只是想把它扔出去,所以至少你可以看到其他选项:

function convertToRoman(num) {
  var value = [];
  var temp, base, buffer;
var letters = ['I', 'V', 'X', 'L', 'C', 'D', 'M'];
  var offsets = [
    [1, 0],  // 1
    [2, 0],  // 2
    [3, 0],  // 3
    [-1, 1], // 4
    [0, 1],  // 5
    [1, 1],  // 6
    [2, 1],  // 7
    [3, 1],  // 8
    [-2, 2],  // 9
  ];
// cascade through each denomination (1000's, 100's, 10's, 1's) so that each denomination is triggered
// Thousands
  if (num >= 1000) {
    temp = Math.floor(num / 1000);
buffer = offsets[temp - 1];
base = 6;
value.push(getValue(base, letters, buffer));
num -= temp * 1000;
  }
// Hundreds
  if (num >= 100) {
    temp = Math.floor(num / 100);
buffer = offsets[temp - 1];
base = 4;
value.push(getValue(base, letters, buffer));
num -= temp * 100;
  }
// Tens
  if (num >= 10) {
    temp = Math.floor(num / 10);
buffer = offsets[temp - 1];
base = 2;
value.push(getValue(base, letters, buffer));
num -= temp * 10;
  }
// Ones
  if (num > 0) {
buffer = offsets[num - 1];
base = 0;
value.push(getValue(base, letters, buffer));
  }
// Finish
return value.join('');
}
function getValue(base, letters, buffer) {
  var val1 = buffer[0], val2 = buffer[1];
  var value = [];
// If val1 is less than 0 then we know it is either a 4 or 9, which has special cases
  if (val1 < 0) {
    // Push the base index, then push the base plus the val2 offset
    value.push(letters[base]);
    value.push(letters[base + val2]);
  } else {
    // Push a letter if val2 is set - meaning we need to offset a number that is equal to or higher than 5
    // 5 is basically the only scenario which this will exist
    if (val2 > 0) value.push(letters[base + val2]);
// Now add in the next letters of the base for the inciment
    for (var i = 0; i < val1; i++) {
      value.push(letters[base]);
    }
  }
return value.join('');
}
convertToRoman(90);
我很确定伴侣功能意味着它可以具有几乎无限的潜力,假设你为大于M的数字提供了正确的符号,但是不要引用我的话。

iid

赞同来自:

如果HTMLElement中的这个数字(例如span),我们建议添加HTML属性data-format

<p>Phase <span data-format="roman">4 </span> Sales</p>
注意:这不是HTML标准。在jsfiddle的html部分向下滚动后,可以看到使用的Javascript代码。

DEMO

uanimi

赞同来自:

如果它仅用于显示目的,请使用带有一点JS的标准HTML作为值(如果需要)和CSS以使其内联:

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