2016-07-13 6 views
0

Следующий алгоритм состоит в том, чтобы преобразовать порядковые числа в римские числа. Он работает для большинства чисел, но для некоторых из них все еще есть проблемы. Например, цифры 500 или 1000 не работают, и я не знаю, почему. Я знаю, что чего-то не хватает; любая помощь?алгоритм javascript, преобразовывающий в римские числа

Код:

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

} 
+0

почему бы не использовать объект разговора вместо массива и необходимость как '{1: 'I', 2: 'II', ...}' –

+0

Это правда, я согласен с вами. Я думаю, что моя проблема в том, что я неправильно начал алгоритм, и я следил за ним, избегая любых изменений. Спасибо!! – galeonweb

ответ

2

@Nina Scholz ответ правильный (а также, элегантный), но учтите, что у вас есть проблемы с нулями (фактически, как римляне были!).

Если вы хотите, чтобы ваш код работал, вам нужно добавить нуль в массив преобразования, первое, что нужно было бы добавить только {0:''}, но затем, как пустую строку, функция фильтра не удастся, поэтому вы можете добавить пробел для ключа «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(); 

} 

Во всяком случае, как я уже сказал, ответом Нины является хорошим.

+0

спасибо, глупый я !!, я не знаю, почему я об этом не думал раньше! и я также думаю, что @Nina прав !. Спасибо вам обоим! – galeonweb

3

Вы можете немного изменить

  • Объект вместо массив объектов.

  • Доступ к значениям.

  • Значение по умолчанию для неизвестных деталей.

  • Затем вы можете опустить фильтрацию для значений 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));

Вы можете сократить его немного больше с diffrent объект для просмотра и для строительства arr и romansArray.

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

+0

Я думаю, вам нужно немного очистить на 'var arr = [num.length]; arr = num.toString(). Split (""). Reverse(); ' –

0

Один из эффективных алгоритмов для чисел до 3999. Он работает как таблица сопоставления.

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

Вот мой ответ:

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

все эти ответы опираются на объекты, которые плохо Becase объекты не имеют порядок

так использовать массивы не испортит

function romanize(num){ 
 
\t if(!+num){ 
 
\t \t return false; 
 
\t } 
 
\t var result = ''; 
 
\t if(num < 0){ 
 
\t \t num = Math.abs(num); 
 
\t \t result = '-'; 
 
\t } 
 
\t var decimal = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]; 
 
\t var roman = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"]; 
 
\t for(var i = 0; i <= decimal.length; i++){ 
 
\t \t while(num % decimal[i] < num){ 
 
\t \t \t result += roman[i]; 
 
\t \t \t num -= decimal[i]; 
 
\t \t } 
 
\t } 
 
\t return result; 
 
} 
 

 
console.log(romanize(9999)); 
 
console.log(romanize(1989));

также быстрый

источник: selftaughtjs

EDIT: по крайней мере, я думаю, что объекты не имеют порядка

Смежные вопросы