罗马数字翻译使用JavaScript

时间:2015-10-03 18:45:23

标签: javascript algorithm

我在不使用下划线的情况下使用此功能,但作为额外的挑战,我尝试使用下划线将罗马数字转换为阿拉伯数字。以下是我的尝试。它起作用,除了" next"数字大于"当前"一。我真的不确定原因,但是当我检查if(下一个> = num)时,if if是否甚至没有被执行?

var DIGIT_VALUES = {
  I: 1,
  V: 5,
  X: 10,
  L: 50,
  C: 100,
  D: 500,
  M: 1000
};

var translateRomanNumeral = function(roman) {
  // if it's not in the digit values object, return null
  for (var i = 0; i < roman.length; i++) {

    if (!(roman[i] in DIGIT_VALUES)) {
      return null;
    }

  }
  //with underscore:
 var romanTranslated =  reduce(roman, function(memo, letter, i) {
    var prev = DIGIT_VALUES[roman[i - 1]];
    var num = DIGIT_VALUES[letter];
    var next = DIGIT_VALUES[roman[i + 1]];
    if (next === undefined || next <= num) {
      return memo + num;
    }

由于某种原因,这不会被执行:

    if (next >= num) {
      var diff = num - prev;
      console.log(diff);
      return memo + (diff - prev);
    }
  }, 0);
  // grab the first one

  //1
  // console.log(num);
return romanTranslated;


};

console.log(translateRomanNumeral("LXIV")); //returns 66 ---> should return 64
console.log(translateRomanNumeral("CI")); //working --> returns 101
console.log(translateRomanNumeral("MMMMCCL")); // working ---> returns 4250.
//works!

2 个答案:

答案 0 :(得分:1)

您可以使用Array#reduce的简洁版本,并查看实际值和下一个值。

&#13;
&#13;
function parseRoman(s) {
    var val = { M: 1000, D: 500, C: 100, L: 50, X: 10, V: 5, I: 1 };
    return s.toUpperCase().split('').reduce(function (r, a, i, aa) {
        return r + (val[a] < val[aa[i + 1]] ? -val[a] : val[a]);
    }, 0);
}

console.log(parseRoman("LXIV"));    //   64
console.log(parseRoman("IX"))       //    9
console.log(parseRoman("IV"))       //    4
console.log(parseRoman("CI"));      //  101
console.log(parseRoman("MMMMCCL")); // 4250
&#13;
&#13;
&#13;

答案 1 :(得分:0)

我的错误的主要来源是我定义reduce的方式不允许我在迭代时访问索引。我更新了我的reduce函数,然后在稍微调试之后就可以了:

var DIGIT_VALUES = {
  I: 1,
  V: 5,
  X: 10,
  L: 50,
  C: 100,
  D: 500,
  M: 1000
};
var each = function(collection, iterator) {
  if (Array.isArray(collection)) {
    for (var i = 0; i < collection.length; i++) {
      iterator(collection[i], i, collection);
    }

  } else {
    for (var key in collection) {
      iterator(collection[key], key, collection);
    }
  }

};

var reduce = function(collection, iterator, total) {
  if (total == undefined) {
    total = collection.shift();
  }


  each(collection, function(val, i) {
    total = iterator(total, val, i);
  })
  return total;
};

var translateRomanNumeral = function(roman) {
  if (typeof(roman) !== 'string') {
    return null;
  }
  if (!roman) {
    return 0;
  }
  // if it's not in the digit values object, return null
  for (var i = 0; i < roman.length; i++) {

    if (!(roman[i] in DIGIT_VALUES)) {
      return null;
    }

  }
  //with underscore:

  return reduce(roman, function(memo, letter, i) {
    var num = DIGIT_VALUES[letter];
     //console.log(i);
    //how do you acess the next item in a collection in reduce?
    var next = DIGIT_VALUES[roman[Number(i) + 1]];
    // console.log(Number(i) + 1);
    // console.log(next);

      if ( next === undefined || next <= num) {
        return memo + num;
        //console.log(memo);
      }

      else {
        // var diff = num - prev;
        // console.log(diff);
        return memo - num;
        // memo = memo + (next - num);
      }


    // return memo;
  }, 0);

};

console.log(translateRomanNumeral("LXIV")); //returns 66 ---> should return 64
console.log(translateRomanNumeral("IX")) // should return 9
console.log(translateRomanNumeral("IV")) /// should return 4

console.log(translateRomanNumeral("CI")); 
//working --> returns 101
console.log(translateRomanNumeral("MMMMCCL")); 
// working ---> returns 4250.
//works!