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

时间:2012-01-31 16:22:14

标签: javascript roman-numerals

如何将整数转换为roman numerals

function romanNumeralGenerator (int) {

}

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

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

警告:仅支持1到3999之间的数字

73 个答案:

答案 0 :(得分:81)

我在这个博客上发现了一个很好用的谷歌:

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

答案 1 :(得分:60)

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

转自位于http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter

的2008年评论

VIEW DEMO

答案 2 :(得分:37)

我不明白为什么每个人的解决方案都很长并且使用多个for循环。

        using (SqlConnection connection = new SqlConnection(_connectionString))
        {
            var adopters = connection.Query<Adopter>("SELECT a.* FROM Adopters a");
            foreach (var adopter in adopters)
            {
                adopter.State = connection.QueryFirst<State>("Select s.* FROM States s WHERE s.Id =  @Id", new { Id = adopter.StateId });
                adopter.Pets = connection.Query<Pet>("Select p.* FROM Pets p WHERE p.AdopterId = @Id", new { Id = adopter.Id });
                foreach (var pet in adopter.Pets)
                {
                    pet.Status = connection.QueryFirst<Status>("Select s.* FROM Status s WHERE s.Id =  @Id", new { Id = pet.StatusId });
                    pet.Gender = connection.QueryFirst<Gender>("Select g.* FROM Genders g WHERE g.Id =  @Id", new { Id = pet.GenderId });
                }
            }

            return adopters;
        }

答案 3 :(得分:13)

这些函数将任何正整数转换为其等效的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;
};

罗马数字字符串到数字:

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

答案 4 :(得分:13)

我在下面开发了递归解决方案。该函数返回一个字母,然后调用自身返回下一个字母。直到传递给函数的数字为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]);
    }
  }
}

答案 5 :(得分:8)

我知道这是一个老问题,但我为这个解决方案感到非常自豪:)它只能处理小于1000的数字,但可以通过添加到'numbersCodes'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">

答案 6 :(得分:5)

<强>的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

找到许多其他建议

答案 7 :(得分:4)

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

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

答案 8 :(得分:3)

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

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

答案 9 :(得分:3)

此函数会将任何小于3,999,999的数字转换为roman。请注意,大于3999的数字将位于text-decoration设置为overline的标签内,这将添加overline,当数字大于3999时,它是x1000的正确表示。 / p>

四百万(4,000,000)将与两个overline进行IV,因此,您需要使用一些技巧来表示,可能是DIV border-top或某些背景图片使用这两个overline s ...每个overline代表x1000。

function convert(num){
    num = parseInt(num);

    if (num > 3999999) { alert('Number is too big!'); return false; }
    if (num < 1) { alert('Number is too small!'); return false; }

    var result = '',
        ref = ['M','CM','D','CD','C','XC','L','XL','X','IX','V','IV','I'],
        xis = [1000,900,500,400,100,90,50,40,10,9,5,4,1];

    if (num <= 3999999 && num >= 4000) {
        num += ''; // need to convert to string for .substring()
        result = '<label style="text-decoration: overline;">'+convert(num.substring(0,num.length-3))+'</label>';
        num = num.substring(num.length-3);
    }

    for (x = 0; x < ref.length; x++){
        while(num >= xis[x]){
            result += ref[x];
            num -= xis[x];
        }
    }
    return result;
}

答案 10 :(得分:3)

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

答案 11 :(得分:2)

如果你想转换一个带有更多符号的大数字,也许这个算法可以提供帮助。

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

set.seed(123456)
   b = c ( 1:5 )  
   n=100
   nb=length(b)
   x = matrix ( rnorm ( nb*n) ,ncol = nb )
   y =  x %*% b + rnorm ( n) 

   l=lm(y~x+0)
   AIC(l)
   residual= (y-x %*% l$coef)
   2*nb-2*sum(dnorm(residual, 0, sd(residual), log=T))
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;
    }

答案 12 :(得分:2)

&#13;
&#13;
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;
&#13;
p {
  color: darkblue;
}
&#13;
<p>Decimal: 3999</p>
<p id="roman">Roman:</p>
&#13;
&#13;
&#13;

答案 13 :(得分:2)

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

答案 14 :(得分:2)

如果 HTMLElement 中的此号码(例如跨度),我们建议添加 HTML属性 data-format

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

注意:这不是HTML标准。在jsfiddle的html部分向下滚动时,可以看到使用的Javascript代码。

DEMO

答案 15 :(得分:2)

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

&#13;
&#13;
=Date()
&#13;
&#13;
&#13;

然后我添加了一个扫描罗马元素的循环,将NUM中最大的仍包含在RESULT中,然后我们减少相同数量的NUM。

就像我们用罗马数字映射NUM的一部分然后我们减少它相同的数量。

&#13;
&#13;
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];
&#13;
&#13;
&#13;

答案 16 :(得分:1)

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

答案 17 :(得分:1)

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

&#13;
&#13;
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;
}
&#13;
<ol class="roman-lowercase"><li value="4"></li></ol> <!-- iv. -->
<ol class="roman-uppercase"><li value="142"></li></ol> <!-- CXLII. -->
&#13;
&#13;
&#13;

答案 18 :(得分:1)

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

答案 19 :(得分:1)

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

答案 20 :(得分:1)

这是一个正则表达式解决方案:

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

答案 21 :(得分:1)

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

答案 22 :(得分:1)

我觉得我的解决方案更具可读性和易懂性。

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

答案 23 :(得分:1)

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

答案 24 :(得分:1)

此功能适用于每个数字中的不同字符集。要添加另一个数字,请将罗马数字字符串添加到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>

答案 25 :(得分:1)

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

答案 26 :(得分:1)

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

答案 27 :(得分:1)

这是我第一次陷入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);

答案 28 :(得分:1)

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

答案 29 :(得分:0)

    const convertToRoman = (n)=>
{
     let u =0;
    let result ='';
    let rL='IVXLCDM';

while (n>0)
{   
    u=n%10;
    switch (u){
          case 1: result =   rL[0] + result ;
          break;
          case 2: result = rL[0]+rL[0] + result;
          break;
          case 3: result = rL[0]+rL[0]+rL[0] + result;
          break;
          case 4: result = rL[0]+rL[1] + result;
          break;
          case 5: result =  rL[1] + result;
          break;
          case 6: result = rL[1] + rL[0] + result;
          break;
          case 7: result =rL[1] + rL[0] +rL[0] + result;
          break;
          case 8: result =  rL[1] + rL[0] +rL[0] + rL[0] + result;
          break;
          case 9: result =  rL[0] + rL[2] + result;
          break;
            };
            rL = rL.substring(2)
// after every last digit.. when conversion is finished.. 
// number is taking another value - same as container with roman Letter


    n=Math.trunc(n/10);
};
return result;
};

我是初学者,我看到的是)))没有arrays。当然,在功能上加上itter + acc会更好。 刚刚通过freeCodeCamp的测试

答案 30 :(得分:0)

可能是最简单的解决方案:

rome = n => {
    b=0
    s=''
    for(a=5; n; b++,a^=7)
        for(o=n%a, n=n/a^0;o--;)
            s='IVXLCDM'[o>2?b+n-(n&=-2)+(o=1):b]+s
    return s
}

r = [rome(892),rome(3999)];

console.log(r);

虽然我不能相信。这是CodeSignal上的vetalperko's解决方案。

答案 31 :(得分:0)

我真的很喜欢jaggedsoft的解决方案,但由于我的代表太低了,所以我无法回答:(:(

我细分了一下,为那些不了解它的人解释了一下。希望它可以帮助某人。

function convertToRoman(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] ) { //while input is BIGGGER than lookup #..1000, 900, 500, etc.
      roman += i; //roman is set to whatever i is (M, CM, D, CD...)
      num -= lookup[i]; //takes away the first num it hits that is less than the input
                    //in this case, it found X:10, added X to roman, then took away 10 from input
                    //input lowered to 26, X added to roman, repeats and chips away at input number
                    //repeats until num gets down to 0. This triggers 'while' loop to stop.    
    }
  }
  return roman;
}


console.log(convertToRoman(36));

答案 32 :(得分:0)

这是我的代码,希望有帮助:

function convertToRoman(num) {
    let numArr = [];//[M,D,C,L,X,V,I]
    let numStr = "";

    //get num Array
    numArr.push(parseInt(num / 1000));
    num %= 1000;
    numArr.push(parseInt(num / 500));
    num %= 500;
    numArr.push(parseInt(num / 100));
    num %= 100;
    numArr.push(parseInt(num / 50));
    num %= 50;
    numArr.push(parseInt(num / 10));
    num %= 10;
    numArr.push(parseInt(num / 5));
    num %= 5;
    numArr.push(num);

    //cancat num String
    for(let i = 0; i < numArr.length; i++) {
        switch(i) {
            case 0://M
                for(let j = 0; j < numArr[i]; j++) {
                    numStr = numStr.concat("M");
                }
                break;
            case 1://D
                switch(numArr[i]) {
                    case 0:
                        
                        break;
                    case 1:
                        if(numArr[i + 1] === 4) {
                            numStr = numStr.concat("CM");
                            i++;
                        }else {
                            numStr = numStr.concat("D");
                        }
                        break;
                }
                break;
            case 2://C
                switch(numArr[i]) {
                    case 0:
                        
                        break;
                    case 1:
                        numStr = numStr.concat("C");
                        break;
                    case 2:
                        numStr = numStr.concat("CC");
                        break;
                    case 3:
                        numStr = numStr.concat("CCC");
                        break;
                    case 4:
                        numStr = numStr.concat("CD");
                        break;
                }
                break;
            case 3://L
                switch(numArr[i]) {
                    case 0:
                        
                        break;
                    case 1:
                        if(numArr[i + 1] === 4) {
                            numStr = numStr.concat("XC");
                            i++;
                        }else {
                            numStr = numStr.concat("L");
                        }
                        break;
                }
                break;
            case 4://X
                switch(numArr[i]) {
                    case 0:
                        
                        break;
                    case 1:
                        numStr = numStr.concat("X");
                        break;
                    case 2:
                        numStr = numStr.concat("XX");
                        break;
                    case 3:
                        numStr = numStr.concat("XXX");
                        break;
                    case 4:
                        numStr = numStr.concat("XL");
                        break;
                }
                break;
            case 5://V
                switch(numArr[i]) {
                    case 0:
                        
                        break;
                    case 1:
                        if(numArr[i + 1] === 4) {
                            numStr = numStr.concat("IX");
                            i++;
                        }else {
                            numStr = numStr.concat("V");
                        }
                        break;
                }
                break;
            case 6://I
                switch(numArr[i]) {
                    case 0:
                        
                        break;
                    case 1:
                        numStr = numStr.concat("I");
                        break;
                    case 2:
                        numStr = numStr.concat("II");
                        break;
                    case 3:
                        numStr = numStr.concat("III");
                        break;
                    case 4:
                        numStr = numStr.concat("IV");
                        break;
                }
                break;
        }
    }
    console.log(numStr);
    return numStr;
}

convertToRoman(3999);

答案 33 :(得分:0)

这是我的单循环解决方案

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 romanNum = "";

  for(key in roman){
      var check = num>=roman[key];
      if(check){
          console.log(romanNum);
          romanNum += key;
          num-= roman[key]; 
      }
  }
  return romanNum
}

convertToRoman(150);

答案 34 :(得分:0)

此解决方案仅运行一个循环,并具有将数字映射到罗马字母的最小对象

function RomantoNumeral(r){
  let result = 0,
      keys = {M:1000, D:500, C:100, L:50, C:100, L:50, X:10, V:5, I:1},
      order = Object.keys(keys),
      rom = Array.from(r) 

  rom.forEach((e, i)=>{
    if( i  < rom.length -1 && order.indexOf(e) > order.indexOf(rom[i+1])){
      result -= keys[e]
    } else {
      result +=keys[e]
    }
  })  
  return result
}

RomantoNumeral('MMDCCCXXXVII') #2837

答案 35 :(得分:0)

循环可能更优雅,但我发现它们很难阅读。提出了一个或多或少的硬编码版本,这些版本很容易理解。只要您了解第一行,其余的就很容易了。

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

答案 36 :(得分:0)

const basicRomanNumeral = 
  ['',
    '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','MM','MMM'
  ];

function convertToRoman(num) {
  const numArray = num.toString().split('');
  const base = numArray.length;
  let count = base-1;
  const convertedRoman = numArray.reduce((roman, digit) => {
    const digitRoman = basicRomanNumeral[+digit + count*10];
    const result = roman + digitRoman;
    count -= 1;
    return result;
  },'');
  return convertedRoman;
}

答案 37 :(得分:0)

var intToRoman = 函数(值){ const romanObj = { 1:'我', 2:'二', 3:'三', 4:'四', 5:'V', 6:'六', 7:'七', 8:'八', 9:'九', 10:'X', 40:'XL' 50:'L', 60:'LX', 70:'LXX' 80:'LXXX', 90:'XC' 100:'C', 400:'CD', 500:'D', 600:'DC', 700:'DCC', 800:'DCCC', 900:'CM', 1000:'M' }; 让罗马值 = ''; 而(值> 0){ 让 x = value.toString().length - 1; 让 y = x == 0 ? 0 : 10 ** x; if(!y) { romanValue += romanObj[value], value=0; } 其他{

        let temp = value % y;
        let multiple = Math.floor(value/y);
        if (romanObj[multiple*y]) {
            romanValue+=romanObj[multiple*y];
        } else {
            console.log('logger of 1996', romanObj[y], y);
            romanValue+=romanObj[y].repeat(multiple);
        }
        value=temp;
    }
}
return romanValue;

答案 38 :(得分:0)

我还没有看到此消息,所以这是一个仅使用字符串操作的有趣解决方案:

var numbers = [1, 4, 5, 7, 9, 14, 15, 19, 20, 44, 50, 94, 100, 444, 500, 659, 999, 1000, 1024];
var romanNumeralGenerator = function (number) {
    return 'I'
        .repeat(number)
        .replace(/I{5}/g, 'V')
        .replace(/V{2}/g, 'X')
        .replace(/X{5}/g, 'L')
        .replace(/L{2}/g, 'C')
        .replace(/C{5}/g, 'D')
        .replace(/D{2}/g, 'M')
        .replace(/DC{4}/g, 'CM')
        .replace(/C{4}/g, 'CD')
        .replace(/LX{4}/g, 'XC')
        .replace(/X{4}/g, 'XL')
        .replace(/VI{4}/g, 'IX')
        .replace(/I{4}/g, 'IV')
};

console.log(numbers.map(romanNumeralGenerator))

答案 39 :(得分:0)

如果有人需要的话,只是添加一个大数字

function convertToRoman(num) {

if (num < 1 ) {
    console.error('Error (fn convertToRoman(num)): Can\'t convert negetive numbers. You provided: ' + num);
    return false;
}
if (+num > 3000000) {
    console.error('Error (fn convertToRoman(num)): Can\'t convert numbers greater than 3000000. 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;
}

function num2let(a, b, c, num) {
    if(num < 4) return a.repeat(num);
    else if (num === 4) return a + b;
    else if (num < 9) return b + a.repeat(num - 5);
    else return a + c;
}

let romanArray = ["I", "V", "X", "L", "C", "D", "M", "Vb", "Xb", "Lb", "Cb", "Db", "Mb"]; // Xb means Xbar

let arr = String(+num).split('').map(el => +el);
let len = arr.length;
let roman = "";
arr.forEach(el => {
    let index = (len - 1) * 2;
    roman += num2let(romanArray[index], romanArray[index  + 1], romanArray[index + 2], el);
    len--;
});

return roman;
}

答案 40 :(得分:0)

    var romanToInt = function(s) {
    var sum = [];
    var obj = {"I":1,"V":5,"X":10,"L":50,"C":100,"D":500,"M":1000};
    for(var i=0;i<s.length;i++){
        if(obj[s[i]]>obj[s[i-1]]){
            sum[i-1] = (obj[s[i]]-obj[s[i-1]])
        }else{
                sum[i]=(obj[s[i]])       
        }
    }
   return sum.reduce((a, b) => a + b, 0);
};

上面的代码使用一个对象来查找值并进行相应的计算。

    var romanToInt = function(s) {
    var sum = [];

    for(var i=0;i<s.length;i++){

        if(s[i]=="I"){
           sum.push(1);
        }else if(s[i]=="V"){
           sum.push(5);   
        }else if(s[i]=="X"){
           sum.push(10);   
        }else if(s[i]=="L"){
           sum.push(50);  
        }else if(s[i]=="C"){
           sum.push(100);  
        }else if(s[i]=="D"){
           sum.push(500); 
        }else if(s[i]=="M"){
           sum.push(1000);  
        }

        if(sum[i-1]<sum[i]){
            sum[i] = sum[i]-sum[i-1]
            sum[i-1] = 0
        }else{
            sum[i] = sum[i]
        }

    }

  return sum.reduce((a, b) => a + b, 0)

};

以上情况下的代码使用if / else-if语句执行相同的操作。此方法执行速度更快,并且内存效率更高。

也可以通过以下方式使用switch语句解决该问题。

  var romanToInt = function(s) {
    var sum = [];

    for(var i=0;i<s.length;i++){

        switch(s[i]){
            case "I":
                sum.push(1);
                break;
            case "V":
                sum.push(5);
                break;
            case "X":
                sum.push(10);
                break;
            case "L":
                sum.push(50);
                break;
            case "C":
                sum.push(100);
                break;
            case "D":
                sum.push(500);
                break;
            case "M":    
                sum.push(1000);
                break;
        }

        if(sum[i-1]<sum[i]){
            sum[i] = sum[i]-sum[i-1]
            sum[i-1] = 0
        }else{
            sum[i] = sum[i]
        }

    }

  return sum.reduce((a, b) => a + b, 0)

};

答案 41 :(得分:0)

function convertToRoman(num: number){
  let integerToRomanMap = new Map<number, string>([
    [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"]
  ])
  if(integerToRomanMap.has(num)){
    return integerToRomanMap.get(num)
  }
  let res = ''
  while(num > 0){
    let len = String(num).length;
    let divisor = Math.pow(10, len - 1)
    let quotient = Math.floor(num/divisor)
    num = num % divisor
    if(integerToRomanMap.has(divisor * quotient)){
      res += integerToRomanMap.get(divisor * quotient)
    }else{
      while(quotient > 0){
        res += integerToRomanMap.get(divisor)
        quotient--;
      }
    }
  }
  return res;
}

答案 42 :(得分:0)

这是我的解决方法:

db.oneOrNone instead of db.one

答案 43 :(得分:0)

function convertToRoman(num) {

    let I = 1
    let IV = 4
    let V = 5
    let IX = 9
    let X = 10
    let XL = 40
    let L = 50
    let XC = 90
    let C = 100
    let CD = 400
    let D = 500
    let CM = 900
    let M = 1000

    let arr = []
    while(num > 0) {
        console.log(num)
        switch(true) {

            case num - M >= 0 :
                arr.push('M')
                num -= M
                break
            case num - CM >= 0 :
                arr.push('CM')
                num -= CM
                break
            case num - D >= 0 :
                arr.push('D')
                num -= D
                break
            case num - CD >= 0 :
                arr.push('CD')
                num -= CD
                break
            case num - C >= 0 :
                arr.push('C')
                num -= C
                break
            case num - XC >= 0 :
                arr.push('XC')
                num -= XC
                break
            case num - L >= 0 :
                arr.push('L')
                num -= L
                break
            case num - XL >= 0 :
                arr.push('XL')
                num -= XL
                break
            case num - X >= 0 :
                arr.push('X')
                num -= X
                break
            case num - IX >= 0 :
                arr.push('IX')
                num -= IX
                break
            case num - V >= 0 :
                arr.push('V')
                num -= V
                break
            case num - IV >= 0 :
                arr.push('IV')
                num -= IV
                break
            case (num - I) >= 0 :
                arr.push('I')
                num -= I
                break
        }
    }

    str = arr.join("")

    return str
}

答案 44 :(得分:0)

好回答。您可以通过编程方式完成此任务,而无需对值进行过多的硬编码。只是您的代码会更长一点。

const convertToRoman = (arabicNum) => {
    const roman_benchmarks = {1: 'I', 5: 'V', 10: 'X', 50: 'L', 100: 'C', 500: 'D', 1000: 'M', 5000: '_V', 10000: '_X', 50000: '_L', 100000: '_C'}; 
    // in the future, you can add higher numbers with their corresponding roman symbols/letters and the program will adjust to the change
    const arabic_benchmarks = [1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 50000, 100000];   // don't forget to include the new numbers here too
    arabicNum = parseInt(arabicNum);
    let proceed = parseInt(arabicNum.toString().length);
    let romanNumeral = '';
    while(proceed){     // the loop continues as long as there's still a unit left in arabicNum
        const temp_denominator = 1 * (10**(arabicNum.toString().length-1)); // determine what multiple of 10 arabicNum is
        const multiple = Math.floor(arabicNum/temp_denominator);        // get its first digit
        const newNum = multiple*temp_denominator;       // regenerate a floored version of arabicNum
        const filtered_two = arabic_benchmarks.filter((x, i) => newNum >= x && newNum<= arabic_benchmarks[i+1] || newNum <= x && newNum>= arabic_benchmarks[i-1]);
            // filter arabic_benchmarks for the 2 boundary numbers newNum falls within
        switch (newNum) {   // check for what roman numeral best describes newNum and assign it to romanNumeral
            case (newNum == filtered_two[0]-temp_denominator ? newNum :''):
               romanNumeral += roman_benchmarks[temp_denominator]+roman_benchmarks[filtered_two[0]]
                break;
            case (newNum == filtered_two[0] ? newNum : ''):
                romanNumeral += roman_benchmarks[filtered_two[0]]
                break;
             case (newNum > filtered_two[0] && newNum < (filtered_two[1]-temp_denominator) ? newNum : ''):
               romanNumeral += roman_benchmarks[filtered_two[0]]
               const factor = multiple < 5 ? (multiple%5)-1 : multiple%5;
                for(let i = 0; i < factor; i++){
                    romanNumeral += roman_benchmarks[temp_denominator];
                }
                break;
            case (newNum == filtered_two[1]-temp_denominator ? newNum : ''):
                romanNumeral += roman_benchmarks[temp_denominator]+roman_benchmarks[filtered_two[1]];
                break;
            case (newNum == filtered_two[1] ? newNum : ''):
                romanNumeral += roman_benchmarks[filtered_two[1]];
                break;
            default:
                break;
        }

        arabicNum = arabicNum - newNum; // reduce arabicNum by its first hierarchy
        proceed--; // continue the loop
    }

    return romanNumeral;
}


答案 45 :(得分:0)

function atalakit (num) {
    var result ="";
    var roman = ["MMM", "MM", "M", "CM", "DCCC", "DCC", "DC", "D", "CD", "CCC", "CC", "C", "XC", "LXXX", "LXX", "LX", "L", "XL", "XXX", "XX", "XI", "X", "IX", "VIII", "VII", "VI", "V", "IV", "III", "II", "I"];
    var arabic = [3000, 2000, 1000, 900, 800, 700, 600, 500, 400, 300, 200, 100, 90, 80, 70, 60, 50, 40, 30, 20, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1];          
    if ( num>0 && num<4000) {
        var arabiclength = arabic.length;
        for ( i=0; arabiclength > i; i++) {
            if (Math.floor(num/arabic[i])>0){
                result += roman[i];
                num -= arabic[i];
            }
        }
    }
    else {
        document.getElementById('text').innerHTML = "too much";
    }
    document.getElementById('text2').innerHTML = result;
}

答案 46 :(得分:0)

字符串方式: (M chiffer 及以下)

        const romanNumerals =   [
                                 ['I', 'V', 'X'],//for ones 0-9
                                 ['X', 'L', 'C'],//for tens 10-90
                                 ['C', 'D', 'M'] //for hundreds 100-900
                                ];
        
        function romanNumUnderThousand(dijit, position) {
                    let val = '';
                    if (position < 3) {
                        const [a, b, c] = romanNumerals[position];
                        switch (dijit) {
                            case '1': val = a;              break;
                            case '2': val = a + a;          break;
                            case '3': val = a + a + a;      break;
                            case '4': val = a + b;          break;
                            case '5': val = b;              break;
                            case '6': val = b + a;          break;
                            case '7': val = b + a + a;      break;
                            case '8': val = b + a + a + a;  break;
                            case '9': val = a + c;          break;
                        }
                    }
                    return val;
                }
    
function convertToRoman(num) {
    num = parseInt(num);
    const str_num = num.toString();
    const lastIndex = str_num.length - 1;
    return [
            `${(num > 999) ? 'M'.repeat(parseInt(str_num.slice(0, lastIndex - 2))) : ''}`,
            `${(num > 99) ? romanNumUnderThousand(str_num[lastIndex - 2], 2) : ''}`,
            `${(num > 9) ? romanNumUnderThousand(str_num[lastIndex - 1], 1) : ''}`,
             romanNumUnderThousand(str_num[lastIndex], 0)
                   ].join('');
}
        convertToRoman(36); 

答案 47 :(得分:0)

这是递归的解决方案,看起来很简单:

const toRoman = (num, result = '') => {
    const map = {
        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,
      };
      for (const key in map) {
        if (num >= map[key]) {
          if (num !== 0) {
            return toRoman(num - map[key], result + key);
          }
        }
      }
      return result;
    };
console.log(toRoman(402)); // CDII
console.log(toRoman(3000)); // MMM
console.log(toRoman(93)); // XCIII
console.log(toRoman(4)); // IV

答案 48 :(得分:0)

这是我的;

function convertToRoman(num) {
let decimalValueArray = [1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000, "bigger"];
let romanNumArray = ["I", "IV", "V", "IX", "X", "XL", "L", "XC", "C", "CD", "D", "CM", "M"];
let resultNumArray = [];
function getRoman(num) {
    for (let i = 0; i < decimalValueArray.length; i++) {
        let decimalElem = decimalValueArray[i];
        if (num === decimalElem || num === 0) {
            resultNumArray.push(romanNumArray[i]);
            return ;

        } else if (decimalElem > num || decimalElem === "bigger") {   //using (decimalElem>num) and then array value of(i-1) to get the highest decimal value from the array.but this doesnt work when highest decimel value is 1000.so added  "bigger" element.
            resultNumArray.push(romanNumArray[i - 1]);
            getRoman(num - (decimalValueArray[i - 1]));
        } else {
            continue;
        }
        return;
    }
}
getRoman(num);
let resultNumber = (resultNumArray.join(""));
return(resultNumber);    }

答案 49 :(得分:0)

它从 1 到 9999 开始工作。如果可能有 10000 的罗马数字,只需将其替换为罗马数字并创建另一个限制 99999。

function convertToRoman(num) {
  const numArray = num.toString().split("")
  const roman = {
    1: "I",
    5: 'V',
    10: 'X',
    50: 'L',
    100: 'C',
    500: "D",
    1000: 'M',
    9999: "LIMIT"
  }

  let numLen = numArray.length;
  let converted = numArray.map((x) => {
    numLen--;
    return x + "0".repeat(numLen)
  })

  let trans = converted.map((x) => {
    let last = "";

    for (let key in roman) {
      if (x.charAt(0) == 0) {
        return ""
      }

      if (key == x) {
        return roman[key];
      }

      if (key > parseInt(x) && last < parseInt(x)) {
        if (last.length == key.length) {
          const ave = (parseInt(last) + parseInt(key)) / 2

          if (x > ave) {
            return roman[last] + roman[key]
          }

          return roman[last].repeat(x.charAt(0));
        }

        if (x.charAt(0) == 9) {
          return roman[key.slice(0, key.length - 1)] + roman[key];
        }

        return roman[last] + roman[key.slice(0, key.length - 1)].repeat(x.charAt(0) - 5)
      }

      last = key
    }
  })

  return trans.join("");
}

for(let i = 1; i < 12; i++) {
    console.log(i, "->", convertToRoman(i))
}

答案 50 :(得分:0)

在此代码中,可以通过向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;
}

答案 51 :(得分:0)

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

答案 52 :(得分:0)

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

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
}

答案 53 :(得分:0)

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

此版本不需要任何硬编码逻辑用于边缘情况,例如4(IV),9(IX),40(XL),900(CM)等。这也意味着理论上它可以处理大于3999的大数,假设连续不超过3个&#34;规则适用。

我已经对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);

答案 54 :(得分:0)

好吧,似乎我不是唯一一个在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以上的一行。我还没有解决。

希望这会对你有所帮助。

答案 55 :(得分:0)

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

答案 56 :(得分:0)

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

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

答案 57 :(得分:0)

这是我的&#34;功能正常&#34; 解决方案。

&#13;
&#13;
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);
&#13;
&#13;
&#13;

答案 58 :(得分:0)

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

答案 59 :(得分:0)

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

&#13;
&#13;
//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++;  
 }
&#13;
&#13;
&#13;

答案 60 :(得分:0)

有几种方法可以做到这一点。我个人更喜欢使用对象并遍历键值对:

const solution=(n)=>{
   const romanLetters ={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 romanNumber ='';
   let valuesArr = Object.values(romanLetters);

   for(let i in valuesArr){
        while (n - valuesArr[i] >= 0){
            romanNumber+=Object.keys(romanLetters)[i]; 
            n-=valuesArr[i];
        }
   }
   return romanNumber;
}

答案 61 :(得分:0)

虽然我的回答并不像其他人那样有效,但我的重点更多的是基本数字不硬编码,并允许程序弄清楚其余部分。
例如......
而不是:
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('');

答案 62 :(得分:0)

我刚刚在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的数字提供了正确的符号,但是不要引用我。

答案 63 :(得分:0)

这是一种方法,无需遍历所有不同的罗马数字及其相应的数字。它具有恒定的时间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;
}

答案 64 :(得分:0)

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

答案 65 :(得分:0)

这是我的解决方案:

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

答案 66 :(得分:0)

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

答案 67 :(得分:0)

&#13;
&#13;
{{1}}
&#13;
&#13;
&#13;

答案 68 :(得分:0)

自从提出这个问题后,看过所有以前的46个“Number-To-Roman”解决方案,kennebec只有一个反向Roman-to-Number的帖子,这有几个问题:“Number”对象不能直接扩展,你需要使用原型。在这种情况下,原型设计也没有意义(String对象是一个更好的候选者,如果有的话)。其次,它是不必要的复杂,并另外调用罗马方法。第三,对于大于4000的数字,它失败了。对于这两种类型的转换,这里有47个帖子的优雅且最简洁。这些转换基本上适用于任何数字。 romanToNumber是gregoryr优雅解决方案的一小部分:

function numberToRoman(val,rom){ //returns empty string if invalid number
  rom=rom||''
  if(isNaN(val)||val==0) 
    return rom;
  for(i=0;curval=[1000,900,500,400,100,90,50,40,10,9,5,4,1][i],i<13;i++)
    if(val >= curval)
	   return numberToRoman(val-curval,rom+['M','CM','D','CD','C','XC','L','XL','X','IX','V','IV','I'][i])
}

function romanToNumber(txtRom){//returns NaN if invalid string
  txtRom=txtRom.toUpperCase();
  if (!/^M*(CM|CD|(D?C{0,3}))?(XC|XL|(L?X{0,3}))?(IX|IV|(V?I{0,3}))?$/.test(txtRom))
    return NaN;
  var retval=0;
  txtRom.replace(/[MDLV]|C[MD]?|X[CL]?|I[XV]?/g, function(i) {
    retval += {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 retval;
}
#tblRoman{border-collapse:collapse;font-family:sans-serif;font-size:.8em}
<h3>Roman to Number Conversion</h3>
<input type="button" value="example 1" onclick="document.getElementById('romanval').value='mmmmmmmcdlxxxiv'">
<input type="button" value="example 2" onclick="document.getElementById('romanval').value='mmmmmmmdclxxxiv'">
<input type="button" value="example 3" onclick="document.getElementById('romanval').value='mmmmmmmdxcdlxxxiv'">
<p>
Enter a Roman Number below, or click on an example button. Then click Convert 
</p>
<input type="text" size="40" id="romanval">
 <input type="button" onclick="document.getElementById('resultval').innerText
 = romanToNumber(document.getElementById('romanval').value)" value="Convert"> 
<p />
Numeric Value: <b id="resultval"></b>

<hr>
<h3>Number to Roman Conversion</h3>
<input type="button" value="Generate table upto 2000" onclick="document.getElementById('tblRoman').innerHTML ='</tr>'+[...Array(2000).keys()].map(x => '<td>'+(x+1)+': '+numberToRoman(x+1)+'</td>'+((x+1)%10==0?'</tr><tr>':'')).join('')+'</tr>'">

<table id="tblRoman" border></table>

答案 69 :(得分:0)

只是连接到Piotr Berebecki的答案。 我编辑它,以便递归函数不仅从给定数字中减去1,而且它会立即减去所提供数组中匹配最多的数字,以加快处理速度。

// the arrays 
var arabicFormat = [1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000];
var romanFormat = ['I', 'IV', 'V', 'IX', 'X', 'XL', 'L', 'XC', 'C', 'CD', 'D', 'CM', 'M'];


function convertToRoman(num) {

 // the recursion will stop here returning a blank
 if (num === 0){
 return '';
 }

 var returnValue = [];

 // this is the main For loop of the function
 for (var i=0; i < arabicFormat.length; i++){

   if (num >= arabicFormat[i]){
    // empty the array on every iteration until it gets to the final number
     returnValue = [];
    // store the current highest matched number in the array
     returnValue.push(romanFormat[i]);
    } 

 }

  // get the correct resulting format 
  returnValue = returnValue.join();

  // get the highest matched number value
  var whatIndex = romanFormat.indexOf(returnValue);
  var substractValue = arabicFormat[whatIndex];

  // here the recursion happens
  return returnValue + convertToRoman(num - substractValue);
}

答案 70 :(得分:0)

我试图通过将阿拉伯数字数组映射到成对的罗马数组来做到这一点。讨厌的3级三元数可以用if(){} else {}块代替,以使其更具可读性。它的工作范围是1到3999,但可以扩展:

function romanize(num) {
  if(num > 3999 || num < 1) return 'outside range!';
  const roman = [ ['M', ''], [ 'C', 'D' ], [ 'X', 'L' ], [ 'I', 'V' ] ];
  const arabic = num.toString().padStart(4, '0').split('');
  return arabic.map((e, i) => {
    return (
      e < 9 ? roman[i][1].repeat(Math.floor(e / 5)) : ''
    ) + (
      e % 5 < 4
        ? roman[i][0].repeat(Math.floor(e % 5))
        : e % 5 === 4 && Math.floor(e / 5) === 0
          ? roman[i][0] + roman[i][1]
          : Math.floor(e / 5) === 1
            ? roman[i][0] + roman[i - 1][0]
            : ''
    );
  }).join('');
}

答案 71 :(得分:-1)

使用此代码:

function convertNumToRoman(num){
  const romanLookUp = {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 result = ''

  // Sort the object values to get them to descending order
  Object.keys(romanLookUp).sort((a,b)=>romanLookUp[b]-romanLookUp[a]).forEach((key)=>{
    while(num>=romanLookUp[key]){
      result+=key;
      num-=romanLookUp[key]
    }
  })
  return result;
}

答案 72 :(得分:-1)

我是从头开始为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));

相关问题