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

发布于 2025-01-01 06:39:45 字数 281 浏览 0 评论 0原文

如何将整数转换为罗马数字

function romanNumeralGenerator (int) {

}

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

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

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

How can I convert integers into roman numerals?

function romanNumeralGenerator (int) {

}

For example, see the following sample inputs and outputs:

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

Caveat: Only support numbers between 1 and 3999

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(30

画尸师 2025-01-08 06:39:45

我使用谷歌发现这个博客上有一篇不错的文章:

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

There is a nice one here on this blog I found using google:

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

function romanize (num) {
    if (isNaN(num))
        return NaN;
    var digits = String(+num).split(""),
        key = ["","C","CC","CCC","CD","D","DC","DCC","DCCC","CM",
               "","X","XX","XXX","XL","L","LX","LXX","LXXX","XC",
               "","I","II","III","IV","V","VI","VII","VIII","IX"],
        roman = "",
        i = 3;
    while (i--)
        roman = (key[+digits.pop() + (i * 10)] || "") + roman;
    return Array(+digits.join("") + 1).join("M") + roman;
}
一曲爱恨情仇 2025-01-08 06:39:45
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

查看演示

function romanize(num) {
  var lookup = {M:1000,CM:900,D:500,CD:400,C:100,XC:90,L:50,XL:40,X:10,IX:9,V:5,IV:4,I:1},roman = '',i;
  for ( i in lookup ) {
    while ( num >= lookup[i] ) {
      roman += i;
      num -= lookup[i];
    }
  }
  return roman;
}

Reposted from a 2008 comment located at: http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter

VIEW DEMO

绝對不後悔。 2025-01-08 06:39:45

我不明白为什么大家的解决方案都那么长并且使用了多个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;
}

I don't understand why everyone's solution is so long and uses multiple for loops.

function convertToRoman(num) {
  var roman = {
    M: 1000,
    CM: 900,
    D: 500,
    CD: 400,
    C: 100,
    XC: 90,
    L: 50,
    XL: 40,
    X: 10,
    IX: 9,
    V: 5,
    IV: 4,
    I: 1
  };
  var str = '';

  for (var i of Object.keys(roman)) {
    var q = Math.floor(num / roman[i]);
    num -= q * roman[i];
    str += i.repeat(q);
  }

  return str;
}
雄赳赳气昂昂 2025-01-08 06:39:45

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

I've developed the recursive solution below. The function returns one letter and then calls itself to return the next letter. It does it until the number passed to the function is 0 which means that all letters have been found and we can exit the recursion.

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

function convertToRoman(num) {
  if (num === 0) {
    return '';
  }
  for (var i = 0; i < romanMatrix.length; i++) {
    if (num >= romanMatrix[i][0]) {
      return romanMatrix[i][1] + convertToRoman(num - romanMatrix[i][0]);
    }
  }
}
对不⑦ 2025-01-08 06:39:45

我个人认为最简洁的方法(无论如何不是最快的)是递归。

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

I personally think the neatest way (not by any means the fastest) is with recursion.

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

This will only support numbers 1-40, but it can easily be extended by following the pattern.

信仰 2025-01-08 06:39:45

这些函数将任何正整数转换为其等效的罗马数字字符串;及其编号的任何罗马数字。

数字到罗马数字:

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

These functions convert any positive whole number to its equivalent Roman Numeral string; and any Roman Numeral to its number.

Number to Roman Numeral:

Number.prototype.toRoman= function () {
    var num = Math.floor(this), 
        val, s= '', i= 0, 
        v = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1], 
        r = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I']; 

    function toBigRoman(n) {
        var ret = '', n1 = '', rem = n;
        while (rem > 1000) {
            var prefix = '', suffix = '', n = rem, s = '' + rem, magnitude = 1;
            while (n > 1000) {
                n /= 1000;
                magnitude *= 1000;
                prefix += '(';
                suffix += ')';
            }
            n1 = Math.floor(n);
            rem = s - (n1 * magnitude);
            ret += prefix + n1.toRoman() + suffix;
        }
        return ret + rem.toRoman();
    }

    if (this - num || num < 1) num = 0;
    if (num > 3999) return toBigRoman(num);

    while (num) {
        val = v[i];
        while (num >= val) {
            num -= val;
            s += r[i];
        }
        ++i;
    }
    return s;
};

Roman Numeral string to Number:

Number.fromRoman = function (roman, accept) {
    var s = roman.toUpperCase().replace(/ +/g, ''), 
        L = s.length, sum = 0, i = 0, next, val, 
        R = { M: 1000, D: 500, C: 100, L: 50, X: 10, V: 5, I: 1 };

    function fromBigRoman(rn) {
        var n = 0, x, n1, S, rx =/(\(*)([MDCLXVI]+)/g;

        while ((S = rx.exec(rn)) != null) {
            x = S[1].length;
            n1 = Number.fromRoman(S[2])
            if (isNaN(n1)) return NaN;
            if (x) n1 *= Math.pow(1000, x);
            n += n1;
        }
        return n;
    }

    if (/^[MDCLXVI)(]+$/.test(s)) {
        if (s.indexOf('(') == 0) return fromBigRoman(s);

        while (i < L) {
            val = R[s.charAt(i++)];
            next = R[s.charAt(i)] || 0;
            if (next - val > 0) val *= -1;
            sum += val;
        }
        if (accept || sum.toRoman() === s) return sum;
    }
    return NaN;
};
半衾梦 2025-01-08 06:39:45

此版本不需要像其他版本那样针对边缘情况(例如 4(IV)、9(IX)、40(XL)、900(CM) 等)进行任何硬编码逻辑。

我已经针对 1-3999 的数据集测试了此代码,它有效。

太长了;

这也意味着该解决方案可以处理大于最大罗马刻度 (3999) 的数字。

似乎有一个交替规则来决定下一个主要罗马数字字符。从 I 开始,乘以 5 得到下一个数字 V,然后乘以 2 得到 X,然后乘以 5 得到 L,然后乘以 2 得到 C,依此类推得到音阶中的下一个主要数字字符。在这种情况下,我们假设“T”被添加到刻度中,以允许比原始罗马刻度允许的 3999 更大的数字。为了保持相同的算法,“T”将代表 5000。

I = 1
V = I * 5
X = V * 2
L = X * 5
C = L * 2
D = C * 5
M = D * 2
T = M * 5

这可以让我们代表从 4000 到 5000 的数字;例如,MT = 4000。


代码:

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

This version does not require any hard coded logic for edge cases such as 4(IV),9(IX),40(XL),900(CM), etc. as the others do.

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

TLDR;

This also means this solution can handle numbers greater than the maximum roman scale could (3999).

It appears there is an alternating rule for deciding the next major roman numeral character. Starting with I multiply by 5 to get the next numeral V and then by 2 to get X, then by 5 to get L, and then by 2 to get C, etc to get the next major numeral character in the scale. In this case lets assume "T" gets added to the scale to allow for larger numbers than 3999 which the original roman scale allows. In order to maintain the same algorithm "T" would represent 5000.

I = 1
V = I * 5
X = V * 2
L = X * 5
C = L * 2
D = C * 5
M = D * 2
T = M * 5

This could then allow us to represent numbers from 4000 to 5000; MT = 4000 for example.


Code:

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);
泡沫很甜 2025-01-08 06:39:45

我知道这是一个老问题,但我对这个解决方案感到非常自豪:)它只能处理小于 1000 的数字,但可以通过添加到“numeralCodes”二维数组来轻松扩展以包含您需要的大小。

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

I know this is an old question but I'm pretty proud of this solution :) It only handles numbers less than 1000 but could easily be expanded to include however large you'd need by adding on to the 'numeralCodes' 2D array.

var numeralCodes = [["","I","II","III","IV","V","VI","VII","VIII","IX"],         // Ones
                    ["","X","XX","XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"],   // Tens
                    ["","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"]];        // Hundreds

function convert(num) {
  var numeral = "";
  var digits = num.toString().split('').reverse();
  for (var i=0; i < digits.length; i++){
    numeral = numeralCodes[i][parseInt(digits[i])] + numeral;
  }
  return numeral;  
}
<input id="text-input" type="text">
<button id="convert-button" onClick="var n = parseInt(document.getElementById('text-input').value);document.getElementById('text-output').value = convert(n);">Convert!</button>
<input id="text-output" style="display:block" type="text">

娇纵 2025-01-08 06:39:45

循环可能更优雅,但我发现它们很难阅读。想出了一个或多或少的硬编码版本,看起来很容易。只要你理解了第一行,剩下的就很简单了。

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

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

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

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

  return roman;
}
调妓 2025-01-08 06:39:45

我创建了两个转换函数。

第一个函数可以使用reduce 将数字转换为罗马数字。
第二个函数与第一个函数非常相似,函数使用相同的方式来转换值。

您需要更改的所有内容都是 _roman 属性。因为您必须根据需要扩展此常量,所以我在那里放置了最大数量 1000 但您可以放置​​更多。

您可以在这里找到更大的罗马数字 https://www.tuomas .salste.net/doc/roman/numeri-romani.html

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

// 1903 => MCMIII
function toRoman(number = 0) {
    return Object.keys(_roman).reduce((acc, key) => {
        while (number >= _roman[key]) {
            acc += key;
            number -= _roman[key];
        }
        return acc;
    }, '');
}


// MCMIII => 1903
function fromRoman(roman = '') {
    return Object.keys(_roman).reduce((acc, key) => {
        while (roman.indexOf(key) === 0) {
            acc += _roman[key];
            roman = roman.substr(key.length);
        }
        return acc;
    }, 0);
}

console.log(toRoman(1903));  // should return 'MCMIII
console.log(fromRoman('MCMIII')); // should return 1903

I created two convert functions.

The first function can convert numbers to roman using reduce.
And the second function is very similar to the first function, the function uses the same way to convert the value.

Everything that you need to change is the _roman property. Because you have to extend this const with scale what you want, I place there max number 1000 but you can put more.

Larger scale with roman numbers you can find here https://www.tuomas.salste.net/doc/roman/numeri-romani.html

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

// 1903 => MCMIII
function toRoman(number = 0) {
    return Object.keys(_roman).reduce((acc, key) => {
        while (number >= _roman[key]) {
            acc += key;
            number -= _roman[key];
        }
        return acc;
    }, '');
}


// MCMIII => 1903
function fromRoman(roman = '') {
    return Object.keys(_roman).reduce((acc, key) => {
        while (roman.indexOf(key) === 0) {
            acc += _roman[key];
            roman = roman.substr(key.length);
        }
        return acc;
    }, 0);
}

console.log(toRoman(1903));  // should return 'MCMIII
console.log(fromRoman('MCMIII')); // should return 1903

染墨丶若流云 2025-01-08 06:39:45

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

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

Here is the solution with recursion, that looks simple:

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

影子的影子 2025-01-08 06:39:45

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

JavaScript

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

many other suggestions can be found at http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter

北音执念 2025-01-08 06:39:45

我创建了两个孪生数组,一个包含阿拉伯数字,另一个包含罗马字符。

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 的一部分映射为罗马数字,然后将其减少相同的数量。

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

I created two twin arrays one with arabic numbers the other with the roman characters.

function convert(num) {

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

Then I added a cycle which scan the roman elements, adding the biggest still comprised in NUM to RESULT, then we decrease NUM of the same amount.

It is like we map a part of NUM in roman numbers and then we decrease it of the same amount.

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

七秒鱼° 2025-01-08 06:39:45

我还没有看到这篇文章,所以这里有一个仅使用字符串操作的有趣解决方案:

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

I didn't see this posted already so here's an interesting solution using only string manipulation:

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

要走就滚别墨迹 2025-01-08 06:39:45

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

四百万 (4,000,000) 将是带有两个上划线的 IV,因此,您需要使用一些技巧来表示,也许是带有 border-topDIV,或带有这两个 overline 的背景图像...每个 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;
}

This function will convert any number smaller than 3,999,999 to roman. Notice that numbers bigger than 3999 will be inside a label with text-decoration set to overline, this will add the overline that is the correct representation for x1000 when the number is bigger than 3999.

Four million (4,000,000) would be IV with two overlines so, you would need to use some trick to represent that, maybe a DIV with border-top, or some background image with those two overlines... Each overline represents x1000.

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

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

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

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

    for (x = 0; x < ref.length; x++){
        while(num >= xis[x]){
            result += ref[x];
            num -= xis[x];
        }
    }
    return result;
}
椵侞 2025-01-08 06:39:45

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

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

var rnumbers = ["I","V","X","L","C","D","M"];
        rnumbers = rnumbers.concat(["V","X","L","C","D","M"].map(function(n) {return '<span style="border-top:1px solid black; padding:1px;">'+n+'</span> '}));
        rnumbers = rnumbers.concat(["V","X","L","C","D","M"].map(function(n) {return '<span style="border:1px solid black; border-bottom:1px none black; padding:1px;">'+n+'</span> '}));
        rnumbers = rnumbers.concat(["V","X","L","C","D","M"].map(function(n) {return '<span style="border-top:3px double black; padding:1px;">'+n+'</span> '}));


    String.prototype.repeat = function( num ) {
        return new Array( num + 1 ).join( this );
    };

    function toRoman(n) {

        if(!n) return "";

        var strn = new String(n);
        var strnlength = strn.length;
        var ret = "";
        for(var i = 0 ; i < strnlength; i++) {
            var index = strnlength*2 -2 - i*2;
            var str;
            var m = +strn[i];
            if(index > rnumbers.length -1) {
                str = rnumbers[rnumbers.length-1].repeat(m*Math.pow(10,Math.ceil((index-rnumbers.length)/2)));
            }else {
                str = rnumbers[index].repeat(m);
                if (rnumbers.length >= index + 2) {
                    var rnregexp = rnumbers[index]
                            .split("(").join('\\(')
                            .split(")").join('\\)');
                    
                    str = str.replace(new RegExp('(' + rnregexp + '){9}'), rnumbers[index] + rnumbers[index + 2])
                            .replace(new RegExp('(' + rnregexp + '){5}'), rnumbers[index + 1])
                            .replace(new RegExp('(' + rnregexp + '){4}'), rnumbers[index] + rnumbers[index + 1])
                }
            }
            ret +=str;
        }

        return ret;
    }
    
<input type="text" value="" onkeyup="document.getElementById('result').innerHTML = toRoman(this.value)"/>

<br/><br/>

<div id="result"></div>

If you want to convert a big number with more symbols, maybe this algo could help.

The only premise for symbols is that must be odd and follow the same rule (1, 5, 10, 50,100 ...., 10^(N)/2, 10^(N)).

var rnumbers = ["I","V","X","L","C","D","M"];
        rnumbers = rnumbers.concat(["V","X","L","C","D","M"].map(function(n) {return '<span style="border-top:1px solid black; padding:1px;">'+n+'</span> '}));
        rnumbers = rnumbers.concat(["V","X","L","C","D","M"].map(function(n) {return '<span style="border:1px solid black; border-bottom:1px none black; padding:1px;">'+n+'</span> '}));
        rnumbers = rnumbers.concat(["V","X","L","C","D","M"].map(function(n) {return '<span style="border-top:3px double black; padding:1px;">'+n+'</span> '}));


    String.prototype.repeat = function( num ) {
        return new Array( num + 1 ).join( this );
    };

    function toRoman(n) {

        if(!n) return "";

        var strn = new String(n);
        var strnlength = strn.length;
        var ret = "";
        for(var i = 0 ; i < strnlength; i++) {
            var index = strnlength*2 -2 - i*2;
            var str;
            var m = +strn[i];
            if(index > rnumbers.length -1) {
                str = rnumbers[rnumbers.length-1].repeat(m*Math.pow(10,Math.ceil((index-rnumbers.length)/2)));
            }else {
                str = rnumbers[index].repeat(m);
                if (rnumbers.length >= index + 2) {
                    var rnregexp = rnumbers[index]
                            .split("(").join('\\(')
                            .split(")").join('\\)');
                    
                    str = str.replace(new RegExp('(' + rnregexp + '){9}'), rnumbers[index] + rnumbers[index + 2])
                            .replace(new RegExp('(' + rnregexp + '){5}'), rnumbers[index + 1])
                            .replace(new RegExp('(' + rnregexp + '){4}'), rnumbers[index] + rnumbers[index + 1])
                }
            }
            ret +=str;
        }

        return ret;
    }
    
<input type="text" value="" onkeyup="document.getElementById('result').innerHTML = toRoman(this.value)"/>

<br/><br/>

<div id="result"></div>

日久见人心 2025-01-08 06:39:45

在测试了本文中的一些实现之后,我创建了一个新的优化实现,以便执行得更快。与其他程序相比,执行时间确实很短,但显然代码更丑陋:)。
使用具有所有可能性的索引数组可能会更快。
以防万一它对某人有帮助。

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

After testing some of the implementations in this post, I have created a new optimized one in order to execute faster. The time execution is really low comparing with the others, but obviously the code is uglier :).
It could be even faster with an indexed array with all the posibilities.
Just in case it helps someone.

function concatNumLetters(letter, num) {
    var text = "";
    for(var i=0; i<num; i++){
        text += letter;
    }
    return text;
}


function arabicToRomanNumber(arabic) {
    arabic = parseInt(arabic);
    var roman = "";
    if (arabic >= 1000) {
        var thousands = ~~(arabic / 1000);
        roman = concatNumLetters("M", thousands);
        arabic -= thousands * 1000;
    }

     if (arabic >= 900) {
         roman += "CM";
         arabic -= 900;
     }

     if (arabic >= 500) {
         roman += "D";
         arabic -= 500;
     }

     if (arabic >= 400) {
         roman += "CD";
         arabic -= 400;
     }

     if (arabic >= 100) { 
        var hundreds = ~~(arabic / 100);
        roman += concatNumLetters("C", hundreds);
        arabic -= hundreds * 100;
     }

     if (arabic >= 90) {
         roman += "XC";
         arabic -= 90;
     }

     if (arabic >= 50) {
         roman += "L";
         arabic -= 50;
     }

     if (arabic >= 40) {
         roman += "XL";
         arabic -= 40;
     }

     if (arabic >= 10) {
        var dozens = ~~(arabic / 10);
        roman += concatNumLetters("X", dozens);
        arabic -= dozens * 10;
     }

     if (arabic >= 9) {
         roman += "IX";
         arabic -= 9;
     }

      if (arabic >= 5) {
         roman += "V";
         arabic -= 5;
     }

     if (arabic >= 4) {
         roman += "IV";
         arabic -= 4;
     }

     if (arabic >= 1) {
        roman += concatNumLetters("I", arabic);
     }

     return roman;
}
无敌元气妹 2025-01-08 06:39:45
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));
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));
千纸鹤 2025-01-08 06:39:45

此函数适用于每个数字中的不同字符集。要添加另一个数字,请在第 1 位、第 5 位和下一个 1 位添加罗马数字字符串。这很好,因为您只需知道下一组使用的字符即可更新它。

function toRoman(n){
  var d=0,o="",v,k="IVXLCDM".split("");
                    
  while(n!=0){
    v=n%10,x=k[d],y=k[d+1],z=k[d+2];
    o=["",x,x+x,x+x+x,x+y,y,y+x,y+x+x,y+x+x+x,x+z][v]+o;
    n=(n-v)/10,d+=2;
  }
  
  return o
}

var out = "";

for (var i = 0; i < 100; i++) {
  out += toRoman(i) + "\n";
}

document.getElementById("output").innerHTML = out;
<pre id="output"></pre>

This function works on the the different character sets in each digit. To add another digit add the roman numeral string the 1 place, 5 place and next 1 place. This is nice because you update it with only knowing the next set of characters used.

function toRoman(n){
  var d=0,o="",v,k="IVXLCDM".split("");
                    
  while(n!=0){
    v=n%10,x=k[d],y=k[d+1],z=k[d+2];
    o=["",x,x+x,x+x+x,x+y,y,y+x,y+x+x,y+x+x+x,x+z][v]+o;
    n=(n-v)/10,d+=2;
  }
  
  return o
}

var out = "";

for (var i = 0; i < 100; i++) {
  out += toRoman(i) + "\n";
}

document.getElementById("output").innerHTML = out;
<pre id="output"></pre>

腹黑女流氓 2025-01-08 06:39:45
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>

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>

抱着落日 2025-01-08 06:39:45

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

I just made this at freecodecamp. It can easily be expanded.

function convertToRoman(num) {

  var roman ="";

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


  for(i=0;i<values.length;i++){
    if(num>=values[i]){
      if(5<=num && num<=8) num -= 5;
      else if(1<=num && num<=3) num -= 1;
      else num -= values[i];
      roman += literals[i];
      i--;
    }
  }


 return roman;
}
风向决定发型 2025-01-08 06:39:45

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

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

Here's a regular expression solution:

function deromanize(roman) {
  var r = 0;
  // regular expressions to check if valid Roman Number.
  if (!/^M*(?:D?C{0,3}|C[MD])(?:L?X{0,3}|X[CL])(?:V?I{0,3}|I[XV])$/.test(roman))
    throw new Error('Invalid Roman Numeral.');

  roman.replace(/[MDLV]|C[MD]?|X[CL]?|I[XV]?/g, function(i) {
    r += {M:1000, CM:900, D:500, CD:400, C:100, XC:90, L:50, XL:40, X:10, IX:9, V:5, IV:4, I:1}[i]; 
  });

  return r;
}
当梦初醒 2025-01-08 06:39:45

我真的很喜欢 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));

I really liked the solution by jaggedsoft but I couldn't reply because my rep is TOO LOW :( :(

I broke it down to explain it a little bit for those that don't understand it. Hopefully it helps someone.

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));
哥,最终变帅啦 2025-01-08 06:39:45

如果 HTMLElement 中有此数字(例如 span),我们建议添加 HTML attribute data-format

Number.prototype.toRoman = function() {
  var e = Math.floor(this),
    t, n = "",
    i = 3999,
    s = 0;
  v = [1e3, 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"];
  if (e < 1 || e > i) return "";
  while (s < 13) {
    t = v[s];
    while (e >= t) {
      e -= t;
      n += r[s]
    }
    if (e == 0) return n;
    ++s
  }
  return ""
};
var fnrom = function(e) {
  if (parseInt(e.innerHTML)) {
    e.innerHTML = parseInt(e.innerHTML).toRoman()
  }
};
setTimeout(function() {
  [].forEach.call(document.querySelectorAll("[data-format=roman]"), fnrom)
}, 10)
Phase <span data-format="roman">4</span> Sales

IF this number in HTMLElement (such as span), we recommend to Add HTML attribute data-format :

Number.prototype.toRoman = function() {
  var e = Math.floor(this),
    t, n = "",
    i = 3999,
    s = 0;
  v = [1e3, 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"];
  if (e < 1 || e > i) return "";
  while (s < 13) {
    t = v[s];
    while (e >= t) {
      e -= t;
      n += r[s]
    }
    if (e == 0) return n;
    ++s
  }
  return ""
};
var fnrom = function(e) {
  if (parseInt(e.innerHTML)) {
    e.innerHTML = parseInt(e.innerHTML).toRoman()
  }
};
setTimeout(function() {
  [].forEach.call(document.querySelectorAll("[data-format=roman]"), fnrom)
}, 10)
Phase <span data-format="roman">4</span> Sales

残疾 2025-01-08 06:39:45
function convertToRoman(num) {
  let roman = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"];
  let arabic = [1000, 900, 500, 400, 100,  90,   50,  40,   10,   9,   5,   4,    1];
  let index = 0;
  let result = "";
  while (num > 0) {
    if (num >= arabic[index]) {
      result += roman[index];
      num -= arabic[index];
    } else index++;
  }

  return result;
}

function convertToRoman(num) {
  let roman = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"];
  let arabic = [1000, 900, 500, 400, 100,  90,   50,  40,   10,   9,   5,   4,    1];
  let index = 0;
  let result = "";
  while (num > 0) {
    if (num >= arabic[index]) {
      result += roman[index];
      num -= arabic[index];
    } else index++;
  }

  return result;
}

南冥有猫 2025-01-08 06:39:45
/*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
/*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
计㈡愣 2025-01-08 06:39:45
function toRoman(n) {
    var decimals = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
    var roman = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'];

    for (var i = 0; i < decimals.length; i++) {
        if(n < 1)
            return "";       

        if(n >= decimals[i]) {
            return roman[i] + toRoman(n - decimals[i]);        
        }
    }
}
function 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]);        
        }
    }
}
旧夏天 2025-01-08 06:39:45

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

This works for all numbers only in need of roman numerals M and below.

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

  var rom = "";
  for(var i=0; i<code.length; i++) {
    while(num >= code[i][0]) {
      rom += code[i][1];
      num -= code[i][0];
    }
  }
  return rom;
}
-残月青衣踏尘吟 2025-01-08 06:39:45

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

This is the first time I really got stuck on freecodecamp. I perused through some solutions here and was amazed at how different they all were. Here is what ended up working for me.

function convertToRoman(num) {
var roman = "";

var lookupObj = {
   1000:"M",
   900:"CM",
   500:"D",
   400:"CD",
   100:"C",
   90:"XC",
   50:"L",
   40:"XL",
   10:"X",
   9:"IX",   
   4:"IV",
   5:"V",
   1:"I",
};

var arrayLen = Object.keys(lookupObj).length;

while(num>0){

 for (i=arrayLen-1 ; i>=0 ; i--){

  if(num >= Object.keys(lookupObj)[i]){

    roman = roman + lookupObj[Object.keys(lookupObj)[i]];        
    num = num - Object.keys(lookupObj)[i];
    break;

  }
 }
}    

return roman;

}

convertToRoman(1231);
素染倾城色 2025-01-08 06:39:45
function convertToRoman(num) {
  var romNumerals = [["M", 1000], ["CM", 900], ["D", 500], ["CD", 400], ["C", 100], ["XC", 90], ["L", 50], ["XL", 40], ["X", 10], ["IX", 9], ["V", 5], ["IV", 4], ["I", 1]];
  var runningTotal = 0;
  var roman = "";
  for (var i = 0; i < romNumerals.length; i++) {
    while (runningTotal + romNumerals[i][1] <= num) {
      runningTotal += romNumerals[i][1];
      roman += romNumerals[i][0];
    }
  }

 return roman;
}
function convertToRoman(num) {
  var 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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文