在Javascript中转换为罗马数字 - 奇怪的错误

时间:2016-08-29 17:13:06

标签: javascript algorithm web

function convertToRoman(num) {

  var thisMap = {

  1:[1],
  2:[1, 1],
  3:[1, 1, 1],
  4:[1, 5],
  5:[5],
  6:[5, 1],
  7:[5, 1, 1],
  8:[5, 1, 1, 1],
  9:[1, 10],
  0:[0]

  };

  var numMap = {

  1000:"M",
  500:"D",
  100:"C",
  50:"L",
  10:"X",
  5:"V",
  1:"I"

  };

  numArr = num.toString().split("");

  var thisIndex = 1;

  var tallyArr = [];

  for (var i = numArr.length - 1; i >= 0; i--) {

   tallyArr.unshift(thisMap[numArr[i]]);

  }

  thisIndex = Math.pow(10, tallyArr.length - 1);

  checkArr = [];

  <<<BUG HERE>>> 

  for (var x = 0; x < tallyArr.length; x++) {

    for (var y = 0; y < tallyArr[x].length; y++) {

      tallyArr[x][y] *= thisIndex;

    }

    thisIndex = thisIndex / 10;

  }

  <<</BUG HERE>>>

  var finalArr = [];

  for (var a = 0; a < tallyArr.length; a++) {

    for (var b = 0; b < tallyArr[a].length; b++) {

      finalArr.push(numMap[tallyArr[a][b]]);

    }

  }

  finalAnswer = finalArr.join("");

  return finalAnswer;

}

convertToRoman(88);

所以这是我在Javascript中将数字转换为罗马数字的功能。它基本上使用thisMap将每个数字格式化为正确的格式,然后使用thisIndex乘以1000,100或10,然后与numMap进行比较以获得正确的罗马数字。

它似乎适用于大多数测试用例,除了44,99或3999。

在这些情况下,似乎将数字乘以错误的数量,因此当它应该是XLIV时,44变为XLXL。

我认为错误发生在&lt;&lt;&gt;&gt;之间标签我已插入,因为这是数字似乎乘以错误的地方。

然而,我无法发现问题。

感谢。

4 个答案:

答案 0 :(得分:0)

试试这个:x循环应该遍历tallyArr的所有长度,除了最后一个。

function convertToRoman(num) {

  // ... code ...

  for (var x = 0; x < tallyArr.length - 1; x++) {
    for (var y = 0; y < tallyArr[x].length; y++) {
      tallyArr[x][y] *= thisIndex;
    }
    thisIndex = thisIndex / 10;
  }

  // ... more code ...
}

答案 1 :(得分:0)

你的解决方案看起来有点过于复杂而且过于复杂,有时候更简单更好,看起来更聪明的答案,寻找过于雄辩的解决方案可能会让你失望。

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

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

  for(var index = 0; index < numMap.length; index++) {
      var value = numMap[index].value,
          limit = numMap[index].limit;
      while(num >= limit) {
        output += value;
        num -= limit;
      }
  }

  return output;
}

alert(convertToRoman(1));
alert(convertToRoman(4));
alert(convertToRoman(5));
alert(convertToRoman(9));
alert(convertToRoman(10));
alert(convertToRoman(88));
alert(convertToRoman(2016));

JSFiddle

答案 2 :(得分:0)

var romanNumber = [
            [1, 'I'], [2, 'II'], [3, 'III'],[4, 'IV'],
            [5, 'V'], [6, 'VI'],[7, 'VII'], [8, 'VIII'],
            [9, 'IX'],[10, 'X']
];


function convertToRoman(number) {
    if (number === 0) {
      return '';
    }
    for (var i = 0; i < romanNumber.length; i++) {
      if (number === romanNumber[i][0]) {
        return romanNumber[i][1];
      }
    }
}
console.log(convertToRoman(1));
console.log(convertToRoman(2));
console.log(convertToRoman(3));
console.log(convertToRoman(4));
console.log(convertToRoman(5));
console.log(convertToRoman(6));
console.log(convertToRoman(7));
console.log(convertToRoman(8));
console.log(convertToRoman(9));
console.log(convertToRoman(10));

答案 3 :(得分:0)

我尝试了另一种方法。

function convertToRoman(num) {
    let arabicArray = [ 1,   4,    5,   9,   10,   40,  50,   90,  100, 400,  500, 900, 1000, 4000, 5000, 5001]
    let romanArray =  ['I', 'IV', 'V', 'IX', 'X', 'XL', 'L', 'XC', 'C', 'CD', 'D', 'CM', 'M', 'MV', 'V', 'limit of 5000']
    let roman = ""
    loop()

    function loop() {
        for (let i = 0; i < arabicArray.length; i++) {
            if (num < arabicArray[i]) {
                roman += romanArray[i - 1]
                num -= arabicArray[i - 1]
                while (num != 0) {loop()} break;
            }
        }
    }

    return roman
}

console.log(convertToRoman(3))

但是,您可以将其限制为5000。