JavaScript算法转换为罗马数字

javascript algorithm converting to roman numbers

本文关键字:罗马 数字 转换 算法 JavaScript      更新时间:2023-09-26

以下算法是将序数转换为罗马数。它适用于大多数数字,但对于其中一些仍然存在问题。例如,数字 500 或 1000 不起作用,我不知道为什么。我知道我错过了什么;有什么帮助吗?

代码为:

function convertToRoman(num) {
  //TABLE OF EQUIVALENCES
  var arrConv=[{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'},{4000:'MMMM'},{5000:'MMMMM'},{6000:'MMMMMM'},{7000:'MMMMMMM'},{8000:'MMMMMMMM'},{9000:'MMMMMMMMM'}];
  //First we break down the number into its units
  //and create an array ex: 652 ==> [600, 50, 2]
  var arr=[num.length];
  arr=num.toString().split("").reverse();
  var i=1;
  for (var k=0;k<arr.length;k++){
    arr.splice(k,1,arr[k]*i);
    i*=10;
  }
  //We make an array of objects with the number and the roman number equivalence
 var romansArray=[];
  for (i=0;i<arr.length;i++){
    var val=arrConv.filter(function(obj){
       return obj[arr[i]];
     })[0];
    romansArray.push(val);
  }
  //I get rid of all the null values
  var result=romansArray.filter(function(val){
    return (val!=null);
  });
  //It returns the string with the roman number
  return result.map(function(value,key){
    return result[key][arr[key]];
  }).reverse().join("");
}

你可以改变一点

  • 一个对象,而不是一个对象数组。

  • 值的访问。

  • 未知部件的默认值。

  • 然后,您可以省略对null值的筛选。

function convertToRoman(num) {
    var arrConv = { 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', 4000: 'MMMM', 5000: 'MMMMM', 6000: 'MMMMMM', 7000: 'MMMMMMM', 8000: 'MMMMMMMM', 9000: 'MMMMMMMMM' };
    var arr = num.toString().split("").reverse(),
        i = 1, k;
    for (k = 0; k < arr.length; k++) {
        arr.splice(k, 1, arr[k] * i);
        i *= 10;
    }
    var romansArray = [];
    for (i = 0; i < arr.length; i++) {
        romansArray.push(arrConv[arr[i]]||'');
    }
    //It returns the string with the roman number
    return romansArray.reverse().join("");
}
console.log(convertToRoman(1000));

您可以使用不同的对象将其缩短一点,以进行查找和构建arrromansArray

function convertToRoman(num) {
    var arrConv = {
            0: { 1: 'I', 2: 'II', 3: 'III', 4: 'IV', 5: 'V', 6: 'VI', 7: 'VII', 8: 'VIII', 9: 'IX' },
            1: { 1: 'X', 2: 'XX', 3: 'XXX', 4: 'XL', 5: 'L', 6: 'LX', 7: 'LXX', 8: 'LXXX', 9: 'XC' },
            2: { 1: 'C', 2: 'CC', 3: 'CCC', 4: 'CD', 5: 'D', 6: 'DC', 7: 'DCC', 8: 'DCCC', 9: 'CM' },
            3: { 1: 'M', 2: 'MM', 3: 'MMM', 4: 'MMMM', 5: 'MMMMM', 6: 'MMMMMM', 7: 'MMMMMMM', 8: 'MMMMMMMM', 9: 'MMMMMMMMM' }
        },
        arr = num.toString().split("").reverse(),
        romansArray = arr.map(function (a, i) {
            return arrConv[i][a] || '';
        });
    return romansArray.reverse().join("");
}
console.log(convertToRoman(1234));

@Nina Scholz 的答案是正确的(而且也很优雅),但请注意,您在零时遇到了麻烦(实际上,就像罗马人一样!

如果你想让你的代码工作,你必须将零添加到转换数组中,第一个想法是只添加{0:''}但随后,作为空字符串,filter 函数将失败,因此您可以为键"0"添加一个空格,最后,应用修剪结果。

像这样:

function convertToRoman(num) {
  //TABLE OF EQUIVALENCES
  var arrConv=[{0:' '},{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'},{4000:'MMMM'},{5000:'MMMMM'},{6000:'MMMMMM'},{7000:'MMMMMMM'},{8000:'MMMMMMMM'},{9000:'MMMMMMMMM'}];
  //First we break down the number into its units
  //and create an array ex: 652 ==> [600, 50, 2]
  var arr=[num.length];
  arr=num.toString().split("").reverse();
  var i=1;
  for (var k=0;k<arr.length;k++){
    arr.splice(k,1,arr[k]*i);
    i*=10;
  }
  //We make an array of objects with the number and the roman number equivalence
 var romansArray=[];
  for (i=0;i<arr.length;i++){
    var val=arrConv.filter(function(obj){
       return obj[arr[i]];
     })[0];
    romansArray.push(val);
  }
  //I get rid of all the null values
  var result=romansArray.filter(function(val){
    return (val!=null);
  });
  //It returns the string with the roman number
  return result.map(function(value,key){
    return result[key][arr[key]];
  }).reverse().join("").trim();
}

无论如何,正如我所说,妮娜的答案是好的。

数字

直到 3999.It 的有效算法之一,其工作原理类似于映射表。

function convertToRoman(num) {
  var arr =[];
  var arr = num.toString().split('');
  var numarry =[];
  var count =0;
  for(var i = arr.length; i>0;i--){
    numarry.push(Number(arr[count])*Math.pow(10,i-1));
    ++count;
  }

var rom =[];
 debugger;
for(var i=0;i<numarry.length;i++)
{
  switch(numarry[i].toString().length){
      case 1:switch(numarry[i]){
        case 0 : rom.push( ''); continue;
        case 1 : rom.push( 'I'); continue;
        case 2 : rom.push( 'II'); continue;
        case 3 : rom.push( 'III'); continue;
        case 4 : rom.push( 'IV'); continue;
        case 5 : rom.push( 'V'); continue;
        case 6 : rom.push( 'VI');  continue;
        case 7 : rom.push( 'VII'); continue;
        case 8 : rom.push( 'VIII'); continue;
        case 9 : rom.push( 'IX'); continue;
        case 10 : rom.push( 'X');  continue; 
        default : rom.push( null);     continue; 
      }continue;
      case 2:switch(numarry[i]){
        case 0 : rom.push( ''); continue;
        case 10 : rom.push( 'X'); continue;
        case 20 : rom.push( 'XX'); continue;
        case 30 : rom.push( 'XXX'); continue;
        case 40 : rom.push( 'XL'); continue;
        case 50 : rom.push( 'L'); continue;
        case 60 : rom.push( 'LX');  continue;
        case 70 : rom.push( 'LXX'); continue;
        case 80 : rom.push( 'LXXX'); continue;
        case 90 : rom.push( 'XC'); continue;
        case 100 : rom.push( 'C'); continue;  
        default : rom.push( null); continue;    
      } continue;
      case 3:switch(numarry[i]){
        case 0 : rom.push( ''); continue;
        case 100 : rom.push( 'C'); continue;
        case 200 : rom.push( 'CC'); continue;
        case 300 : rom.push( 'CCC'); continue;
        case 400 : rom.push( 'CD'); continue;
        case 500 : rom.push( 'D'); continue;
        case 600 : rom.push( 'DC');  continue;
        case 700 : rom.push( 'DCC'); continue;
        case 800 : rom.push( 'DCCC'); continue;
        case 900 : rom.push( 'CM'); continue;
        case 1000 : rom.push( 'M');  continue; 
        default : rom.push( null);continue;      
      } continue;
      case 4:switch(numarry[i]){
        case 0 : rom.push( ''); 
        case 1000 : rom.push( 'M'); continue;
        case 2000 : rom.push( 'MM'); continue;
        case 3000 : rom.push( 'MMM'); continue;
        default : rom.push( null);      
      } continue;

  }

}
  return rom.join('') ;
}
convertToRoman(500);

这是我的答案:

function convertToRoman(num) {
  var tempResult=[];
  var result=[];

    var romanNumbers={0:" ", 1: "I", 2: "II", 3:"III", 4:"IV", 5:"V",  6: "VI", 7:"VII", 8:"VIII", 9:"IX", 10:"X", 20:"XX", 30:"XXW", 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", 2000:"MM", 3000:"MMM" };
  var arr= num.toString().split("");

  for(var k=0; k< arr.length; k++){
    arr.splice(k,1, arr[k]*1);
  }
  var arrLength=arr.length;
  for(var k=arrLength-1; k>=0; k--){
    tempResult.push(romanNumbers[arr[k] * Math.pow(10, arrLength - (k+1)) ]);
  }

//   Getting rid of empty spaces
  for(var j=tempResult.length; j>=0; j--){
    if (tempResult[j]===" "){
      tempResult.splice(j, 1);
    }
  }
  result=tempResult.reverse().join("");
 return result;
}
convertToRoman(1000);

所有这些答案都依赖于对象,这很糟糕,因为对象没有顺序

所以使用数组不要搞砸

function romanize(num){
	if(!+num){
		return false;
	}
	var result = '';
	if(num < 0){
		num = Math.abs(num);
		result = '-';
	}
	var decimal = [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 <= decimal.length; i++){
		while(num % decimal[i] < num){
			result += roman[i];
			num -= decimal[i];
		}
	}
	return result;
}
console.log(romanize(9999));
console.log(romanize(1989));

它也是最快的

来源: 自学成才

编辑:至少我认为对象没有顺序