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

96

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

function romanNumeralGenerator (int) {

}
例如,看下面的样例输入和输出:
1 = "I"
5 = "V"
10 = "X"
20 = "XX"
3999 = "MMMCMXCIX"

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

96个回答

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

2
欢迎来到stackoverflow,请在答案中写下你所做的事情,而不仅仅是代码:http://meta.stackexchange.com/questions/148272/is-there-any-benefit-to-allowing-code-only-answers-while-blocking-code-only-ques - Shalev Shalit
2
这是最圆周率的帖子。#31415926: https://dev59.com/DWox5IYBdhLWcg3wnlpI#31415926 :) - user6123979

1

仍然为此感到自豪 :) 它可以在1-3999之间工作。

var converterArray = [{"1":["I","IV","V","IX"],
                       "2":["X","XL","L","XC"],
                       "3":["C","CD","D","CM"],
                       "4":["M"]}
                     ];

function convertToRoman(num) {
  var romanNumeral = [];
  var numArr = num.toString().split('');
  var numLength = numArr.length;

  for (var i = 0; i<numArr.length; i++) {
    if (numArr[i] < 4) {
      for (var j = 0; j<numArr[i]; j++) {
        romanNumeral.push(converterArray[0][numLength][0]);
      }
    } else if (numArr[i] < 5) {
       for (var j = 3; j<numArr[i]; j++) {
        romanNumeral.push(converterArray[0][numLength][1]);
      }
    } else if (numArr[i] < 9) {
        romanNumeral.push(converterArray[0][numLength][2]);
        for (var j = 5; j<numArr[i]; j++) {
          romanNumeral.push(converterArray[0][numLength][0]);
      }
    } else if (numArr[i] < 10) {
        for (var j = 8; j<numArr[i]; j++) {
          romanNumeral.push(converterArray[0][numLength][3]);
      }
    }
    numLength--;
   }

 return romanNumeral.join('');
}

convertToRoman(9);

这个太大且过于复杂。 - August
谢谢您的反馈,您说得非常正确!我一个星期前写的,现在稍微重构了一下。 - Zsiga

1

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

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

1

这是我用单个循环的解决方案

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

1
我的解决方案将数字拆分成字符串数组,根据其相对于数组长度的位置为每个元素添加零,将带有零的新字符串转换为罗马数字,然后将它们重新连接在一起。这仅适用于3999以下的数字:
function convertToRoman(num){
  var rnumerals = { 1 : 'I', 2 : 'II', 3 : 'III', 4 : 'IV', 5 : 'V', 6   : 'VI', 7 : 'VII', 
  8 : 'VIII', 9 : 'IX', 10 : 'X', 20 : 'XX', 30 : 'XXX', 40 : 'XL', 50 : 'L', 
  60 : 'LX', 70 : 'LXX', 80 : 'LXXX', 90 : 'XC', 100 : 'C', 200 : 'CC', 300 : 'CCC', 
  400 : 'CD', 500 : 'D', 600 : 'DC', 700 : 'DCC', 800 : 'DCCC', 900 : 'CM', 
  1000: 'M', 2000: 'MM', 3000: 'MMM'};

  var zeros, romNum;
  var arr = num.toString().split("");
  var romArr = [];
  for(var i=0; i < arr.length; i++){
    zeros = "0".repeat((arr.length - i - 1));
    arr[i] = arr[i].concat(zeros);
    romArr.push(rnumerals[(arr[i])]); 
  }
  romNum = romArr.join('');
  return romNum;
}

1
const romanSymbols = {
    '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 intToRoman = function(num) {
    if(isNaN(num)) return false;
    if(num==0) return '';

    for (let key in romanSymbols) {
        if(num >= romanSymbols[key] && num > 0) {
            num = num - romanSymbols[key];
            return result = key + intToRoman(num);
        }
    }
};

const romanToInt = function(roman) {
    if(!isNaN(roman)) return 0;
    if(roman=='' || roman=='undefined') return 0;

    for (let key in romanSymbols) {
        if(roman.indexOf(key)===0) {
            roman = roman.replace(key, '');
            return romanSymbols[key] + parseInt(romanToInt(roman));
        }
    }
};

const romanSymbols = {
    '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,
};

const intToRoman = function(num) {
    if(isNaN(num)) return false;
    if(num==0) return '';

    for (let key in romanSymbols) {
        if(num >= romanSymbols[key] && num > 0) {
            num = num - romanSymbols[key];
            return result = key + intToRoman(num);
        }
    }
};

const romanToInt = function(roman) {
    if(!isNaN(roman)) return 0;
    if(roman=='' || roman=='undefined') return 0;

    for (let key in romanSymbols) {
        if(roman.indexOf(key)===0) {
            roman = roman.replace(key, '');
            return romanSymbols[key] + parseInt(romanToInt(roman));
        }
    }
};

function convertRoman() {
    val = document.getElementById('textId').value;
    var resp = intToRoman(val)
    console.log('result:', resp);
}

function convertInt() {
    val = document.getElementById('textId').value;
    var resp = romanToInt(val)
    console.log('result:', resp);
}
<input id="textId" />
<button id="submitBtn" onclick="convertInt()">To Interger</button>
<button id="submitBtn" onclick="convertRoman()">To Roman</button>


你的回答可以通过提供更多的支持性信息来改进。请编辑以添加进一步的细节,比如引用或文档,以便他人可以确认你的回答是否正确。你可以在帮助中心找到关于如何撰写好回答的更多信息。 - undefined
非常感谢你,Sandesh!你帮了我大忙!非常有用!谢谢你。 - undefined

0

只是回应Piotr Berebecki的答案。 我对它进行了编辑,使得递归函数不仅从给定的数字中减去1,而且立即从提供的数组中减去最高匹配的数字以加快进程。

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


function convertToRoman(num) {

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

 var returnValue = [];

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

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

 }

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

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

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

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

RomanNumerals = {
  romerate: function(foo) {
    var bar = '';
    romanNumerals.forEach(function(buzz) {
      while (foo >= buzz[1]) {
        bar += buzz[0];
        foo -= buzz[1]; 
      }
    });
    return bar;
  },
  numerate: function(x) {
    var y = 0;
    romanNumerals.forEach(function(z) {
      while (x.substr(0, z[0].length) == z[0]) {
        x = x.substr(z[0].length);
        y += z[1];
      }
    });
    return y;
  }
};

0

我尝试通过将阿拉伯数字的数组映射到罗马数字对的数组来实现这一点。可恶的三层三元运算符可以被if() {} else{}块替换以使其更易读。它适用于1到3999,但可以扩展:

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

0
function convertToRoman(int) {
    console.log('Number:', int);
    let roman = [];
    let i, k, replacement;
    let seq = ['I', 'V', 'X', 'L', 'C', 'D', 'M'];

    while (int > 999) {
        roman.push('M');
        int -= 1000;
    }
    while (int > 499) {
        roman.push('D');
        int -= 500;
    }
    while (int > 99) {
        roman.push('C');
        int -= 100;
    }
    while (int > 49) {
        roman.push('L');
        int -= 50;
    }
    while (int > 9) {
        roman.push('X');
        int -= 10;
    }
    while (int > 4) {
        roman.push('V');
        int -= 5;
    }
    while (int >= 1) {
        roman.push('I');
        int -= 1;
    }

    // Replace recurrences of 4 ('IIII' to 'IV')
    for (i = 0; i < roman.length; i++) {
        if (roman[i] == roman[i + 1] &&
            roman[i] == roman[i + 2] &&
            roman[i] == roman[i + 3]) {
            for (k = 0; k < seq.length; k++) {
                if (roman[i] == seq[k]) {
                    replacement = seq[k + 1];
                }
            }
            roman.splice(i + 1, 3, replacement);
        }
    }

    // Converting incorrect recurrences ('VIV' to 'IX')
    for (i = 0; i < roman.length; i++) {
        if (roman[i] == roman[i + 2] && roman[i] != roman[i + 1]) {
            for (k = 0; k < seq.length; k++) {
                if (roman[i] == seq[k]) {
                    replacement = seq[k + 1];
                }
            }
            roman[i + 2] = replacement;
            roman.splice(i, 1);
        }
    }

    roman = roman.join('');
    return roman;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接