【问题标题】:Convert a number into a Roman numeral in JavaScript在 javaScript 中将数字转换为罗马数字
【发布时间】:2012-02-23 09:04:57
【问题描述】:

如何将整数转换为roman numerals

function romanNumeralGenerator (int) {

}

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

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

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

【问题讨论】:

    标签: javascript roman-numerals


    【解决方案1】:

    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 };
    
    function toRoman(number = 0) {
        return Object.keys(_roman).reduce((acc, key) => {
            while (number >= _roman[key]) {
                acc += key;
                number -= _roman[key];
            }
            return acc;
        }, '');
    }
    
    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

    【讨论】:

      【解决方案2】:

      var intToRoman = function(value) {
          const romanObj = {
              1: 'I',
              2: 'II',
              3: 'III',
              4: 'IV',
              5: 'V',
              6: 'VI',
              7: 'VII',
              8: 'VIII',
              9: 'IX',
              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'
          };
          let romanValue = '';
          while(value>0){
              let x = value.toString().length - 1;
              let y = x == 0 ? 0 : 10 ** x;
              if(!y) { romanValue += romanObj[value], value=0; }
              else {
                  
                  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;
      }
      
      console.log(intToRoman(18))

      【讨论】:

        【解决方案3】:

        递归,转换前加1,后减1:

        const toRoman = (num, i="I", v="V", x="X", l="L", c="C", d="D", m="M") =>
            num ? toRoman(num/10|0, x, l, c, d, m, "?", "?", num%=10) +
                  (i + ["",v,x][++num/5|0] + i.repeat(num%5)).replace(/^(.)(.*)\1/, "$2")
                : "";
        
        console.log(toRoman(3999));

        【讨论】:

          【解决方案4】:

          此版本不需要像其他版本那样针对诸如4(IV),9(IX),40(XL),900(CM), etc. 之类的边缘情况进行任何硬编码逻辑。

          我已经针对 1-3999 的数据集测试了这段代码,它可以工作。

          TLDR;

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

          似乎有一个交替规则来决定下一个主要的罗马数字字符。首先乘以 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);
          

          【讨论】:

          • 为什么会遭到反对?这是一个按原样工作的示例,可以回答问题并且有很好的文档记录?
          【解决方案5】:

          婴儿的糖果。

          首先,您必须将 romam 映射到对象中的基数:

          const _numbersMap = {
              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
          }
          
          /* The CM, CD, XC, XL, IX and IV properties are
          only needed for the cardinalToRoman() function below. */
          

          注意:如果你只需要将roman转换为cardinal,那么你就不需要上面对象中带有两个romans char的属性了。

          然后你构建一个函数来将基数转换为罗马数字:

          // The funciton receives a cardinal as parameter (of integer type)
          const cardinalToRoman = num => {
          
              // M is the last char in the roman numeric system. Just preventing crashes.
              if (num >= 4000) {
                  console.log('Number is too big'); 
                  return
              }
          
              let roman = ''; // The initial roman string
          
              // It iterates over the _numbersMap object's properties
              for (var i of Object.keys(_numbersMap)) {
          
                  /* For each iteration, it will calculate the division of the
                  given number by the value of the property beeing iterated. */
                  var q = Math.floor(num / _numbersMap[i]);
          
                  /* So the value, multiplied by the current property's value,
                  will be subtracted from the given number */
                  num -= q * _numbersMap[i]; 
          
                  /* The result will be the times that the key of the
                  current property (its respective roman sting) will be repeated
                  in the final string */
                  roman += i.repeat(q); 
              }
          
              return roman;
          };
          

          最后,如果你想求逆,然后构建一个函数将罗马转换为基数:

          // The funciton receives a roman number as parameter (of srting type)
          const romanToCardinal = roman => {
          
              let num = 0; // Initial integer number
              
              /* Let's split the roman string in a Array of chars, and then
              put it in reverse order */
              const romansArray = Array.from(roman).reverse();
              
              // Then let's iterate the array
              romansArray.forEach((char, index, array) => {
                      
                  /* We take the integer number corresponding to the current
                  and the previous chars in the iteration. */
                  const currentNumChar = _numbersMap[char];
                  const prevNumChar = _numbersMap[array[index - 1]];
                  
                  // Throws error if the char is unknown.
                  if (!currentNumChar) {
                      console.error(`The charecter "${char}" of the given roman number "${roman}" is invalid as a roman number char.`);
                      return false;
                  }
                  
                  /* The integer corresponding to the current char is 
                  subtracted from the result if it's bigger than the previous
                  integer. If itsn't, the integer is summed to the result */
                  if (prevNumChar && prevNumChar > currentNumChar) {
                      num -= currentNumChar;
                  } else {
                      num += currentNumChar;
                  }
                  
              });
              
              return num;
          }
          

          试试JSFiddle

          【讨论】:

          • 请尽量给出正确的答案解释。
          • @Tyler2P 请给它评分!
          【解决方案6】:

          它从 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))
          }

          【讨论】:

            【解决方案7】:

            如果有人需要,只是添加大数字

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

            【讨论】:

              【解决方案8】:

              给你。

              function check(digit, char1, char2, char3) {
                if(digit <=3) {
                  return char1.repeat(digit)
                }if(digit == 4){
                  return char1+char2
                }if(digit == 5) {
                  return char2
                }if (digit > 5 && digit < 9) {
                  return char2+char1.repeat(digit-5)
                }if(digit == 9) {
                  return char1+char3
                }
              }
              
              function convertToRoman(num) {
                let result;
                let numList = String(num).split("").reverse()
                result = [check(parseInt(numList[0]), 'I', 'V', 'X'),check(parseInt(numList[1]), 'X', 'L', 'C'),check(parseInt(numList[2]), 'C', 'D', 'M'),'M'.repeat(parseInt(numList[3]))]
              
               return result.reverse().join('');
              }
              
              let res = convertToRoman(2);
              console.log(res)
              

              【讨论】:

                【解决方案9】:
                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;
                }
                

                【讨论】:

                  【解决方案10】:

                  如果HTMLElement中有这个数字(如span),建议添加HTML属性 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 &lt;span data-format="roman"&gt;4&lt;/span&gt; Sales

                  【讨论】:

                    【解决方案11】:
                    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
                    }
                    

                    【讨论】:

                    • 请添加一些关于您添加的代码的说明。它将帮助读者更好地理解它。
                    • 来自 FCC Med 的问题。 JS 脚本。 Answer 具有嵌套在 while 循环内的 switch 语句。最初卡住了,突破来自为十分之一、百分之一、千分之一的数字添加第 4 位和第 9 位的变量。所以 IV 为 4、IX、9、XL、40
                    【解决方案12】:

                    字符串方式: (适用于 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); 
                    

                    【讨论】:

                      【解决方案13】:

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

                      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

                      【讨论】:

                        【解决方案14】:

                        这是我的;

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

                        【讨论】:

                          【解决方案15】:
                          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;
                          }
                          

                          【讨论】:

                            【解决方案16】:

                            很好的回应。您可以通过编程方式完成此操作,而无需对这些值进行过多的硬编码。只是你的代码会长一点。

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

                            【讨论】:

                              【解决方案17】:

                              使用此代码:

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

                              【讨论】:

                                【解决方案18】:

                                这是我的解决方案:

                                var roman = "MX";
                                
                                function solution(roman) {
                                  var val = 0;
                                  for (let i = 0; i < roman.length; i++) {
                                    if (roman.charAt(i) == 'I') {
                                      if (roman.charAt(i + 1) == 'V') {
                                        val += 4;   // IV
                                      } else if (roman.charAt(i + 1) == 'X') {
                                        val += 9;   // IX
                                      } else {
                                        val += 1;   // I
                                      }
                                    } else if (roman.charAt(i) == 'V') {
                                      if (roman.charAt(i - 1) == 'I') {
                                        val = val;
                                      } else {
                                        val += 5;   // V
                                      }
                                    } else if (roman.charAt(i) == 'X') {
                                      if (roman.charAt(i - 1) == 'I') {   // Check if there is I before X
                                        val = val;
                                      }else if (roman.charAt(i + 1) == 'L') {
                                        val += 40;  // XL
                                      } else if (roman.charAt(i + 1) == 'C') {
                                        val += 90;  // XC
                                      } else {
                                        val += 10;  // X
                                      }
                                    } else if (roman.charAt(i) == 'L') {
                                      if (roman.charAt(i - 1) == 'X') {   // Check if there is X before L
                                        val = val;
                                      } else {
                                        val += 50;  // L
                                      }
                                    } else if (roman.charAt(i) == 'C') {
                                      if (roman.charAt(i - 1) == 'X') {
                                        val = val;  // XC
                                      }else if (roman.charAt(i + 1) == 'D') {
                                        val += 400;  // CD
                                      } else if (roman.charAt(i + 1) == 'M') {
                                        val += 900;  // CM
                                      } else {
                                        val += 100;  // C
                                      }
                                    } else if (roman.charAt(i) == 'D') {
                                      if (roman.charAt(i - 1) == 'C') {
                                        val = val;  // CD
                                      } else {
                                        val += 500; // D
                                      }
                                    } else if (roman.charAt(i) == 'M') {
                                      if (roman.charAt(i - 1) == 'C') {
                                        val = val;  // CM
                                      } else {
                                        val += 1000; // M
                                      }
                                    }
                                  }
                                  return val;
                                }
                                console.log(solution(roman));  // The answer is: 1010
                                

                                【讨论】:

                                  【解决方案19】:
                                      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)
                                  
                                  };
                                  

                                  【讨论】:

                                    【解决方案20】:

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

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

                                    【讨论】:

                                      【解决方案21】:
                                          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;
                                      };
                                      

                                      我是初学者,我看到这样 ))) 没有数组。当然,在函数中使用 itter + acc 会更好.. 刚刚通过freeCodeCamp的测试

                                      【讨论】:

                                        【解决方案22】:

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

                                        【讨论】:

                                          【解决方案23】:

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

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

                                          【讨论】:

                                            【解决方案24】:

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

                                            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
                                            

                                            【讨论】:

                                              【解决方案25】:
                                              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));
                                              

                                              【讨论】:

                                              • 请解释您的解决方案
                                              • 让我们取 1012 所以它不等于任何键并且也大于 1000 这是我的第一个键所以它会进入第二个如果条件之后它会找到商这将是 1 所以它将获取结果并将 M*1 添加到其中,因此现在结果变量中将包含 M,并且 num 将为 12。所以现在 12>10 再次进入并执行相同的操作,因此现在结果将变为 MX 和 num = 2 和 2>1,所以它会添加 MXI,现在 num = 1。所以现在它会进入第一个 if 条件并使结果 = MXII。
                                              【解决方案26】:

                                              这是我的单循环解决方案

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

                                              【讨论】:

                                                【解决方案27】:

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

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

                                                【讨论】:

                                                  【解决方案28】:

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

                                                  【讨论】:

                                                    【解决方案29】:

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

                                                    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 解决方案。

                                                    【讨论】:

                                                      【解决方案30】:

                                                      我用谷歌在这个博客上找到了一个不错的:

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

                                                      【讨论】:

                                                      • 提醒:这应该更好地返回 NaN 或 throw 而不是返回 false,如该帖子中所述。
                                                      • 我刚刚发现使用这个函数的最大数字是715799999999 (715,799,999,999)。较大的数字要么不返回任何内容,要么(对于非常大的数字)输出RangeError: Invalid array length 错误。否则,它可以完美运行。谢谢!
                                                      • @tukusejssirs 幸运的是罗马数字是用于多年的,否则会有大于 1000 的数字。但很高兴知道!
                                                      猜你喜欢
                                                      • 2012-10-27
                                                      • 2019-01-09
                                                      • 2011-10-25
                                                      • 1970-01-01
                                                      • 1970-01-01
                                                      • 1970-01-01
                                                      • 2012-10-09
                                                      相关资源
                                                      最近更新 更多