JS中的Roman to Integer为什么它只转换第一个字符

时间:2018-04-04 20:18:28

标签: javascript integer roman-numerals

我尝试解决Leedcode问题13,问题是给定罗马数字,将其转换为整数。(输入保证在1到3999之间。) 这是我下面的代码,我想知道为什么它只将罗马数字中的第一个字符转换为整数?

     var romanToInt = function(s) {
       var result=0;
       if (s==null){
           result=0;
       }
       var myMap=new Map();
       myMap.set('I', 1);
       myMap.set('V', 5);
       myMap.set('X', 10);
       myMap.set('L', 50);
       myMap.set('C', 100);
       myMap.set('D', 500);
       myMap.set('M', 1000);

       var len=s.length;
       for(var i=0;i<len;i++){
           if(myMap.get(s.charAt(i))<myMap.get(s.charAt(i+1))){
               result-=myMap.get(s.charAt(i))
           }
           else{result+=myMap.get(s.charAt(i))
       }
       return result;
   };
   }
   romanToInt('VI');
   romanToInt('V');
   romanToInt('VII');

8 个答案:

答案 0 :(得分:2)

由于

return result;

在一次迭代后结束循环。将它向下移动一行。如果你要做正确的格式化,你就不会犯这样的错误;)

const values = new Map([
  ['I', 1],
  ['V', 5],
  ['X', 10]
  /*....*/
]);

function romanToInt(string) {
  let result = 0,
    current, previous = 0;
  for (const char of string.split("").reverse()) {
    current = values.get(char);
    if (current >= previous) {
      result += current;
    } else {
      result -= current;
    }
    previous = current;
  }
  return result;
}

console.log(romanToInt('I'));
console.log(romanToInt('II'));
console.log(romanToInt('III'));
console.log(romanToInt('IV'));
console.log(romanToInt('V'));
console.log(romanToInt('VI'));
console.log(romanToInt('VII'));
console.log(romanToInt('VIII'));
console.log(romanToInt('IX'));
console.log(romanToInt('X'));
console.log(romanToInt('XI'));
console.log(romanToInt('XII'));
console.log(romanToInt('XIII'));
console.log(romanToInt('XIV'));
console.log(romanToInt('XV'));
console.log(romanToInt('XVI'));
console.log(romanToInt('XVII'));
console.log(romanToInt('XVIII'));
console.log(romanToInt('XIX'));
console.log(romanToInt('XX'));

答案 1 :(得分:2)

由于您的return result;位于内部循环中,因此只需将return result;移至外部循环。

以下是您的代码的简化(可读性)版本。

const myMap=new Map();
myMap.set('I', 1);
myMap.set('V', 5);
myMap.set('X', 10);
myMap.set('L', 50);
myMap.set('C', 100);
myMap.set('D', 500);
myMap.set('M', 1000);

var romanToInt = function(s) {
   var result=0;
   if(s){
     var s1=s.split('');
     s1.forEach(function(e,i){
          result += myMap.get(e) < myMap.get(s1[i+1]) ? -myMap.get(e) : myMap.get(e);  // used ternary oprator with '-' where required
     });
   }
   return result; //move it outside loop
}
console.log(romanToInt('IV'));
console.log(romanToInt('V'));
console.log(romanToInt('VII'));

答案 2 :(得分:0)

也许您可以尝试:

function romanToInt(romanString) {
   if(typeof romanString !== 'string') return NaN;
   const romanRegExp = /^(?=[MDCLXVI])(M*)(?:(C)(?:(D)|(M))|(D?)(C{0,3}))(?:(X)(?:(L)|(C))|(L?)(X{0,3}))(?:(I)(?:(V)|(X))|(V?)(I{0,3}))$/i;
   let parts = romanString.match(romanRegExp);
   if(!parts) return NaN;
   let result = 0;
   [0, 1000, -100,500,1000,500,100, -10,50,100,50,10, -1,5,10,5,1].forEach(
      (weight, i) => result += weight * (parts[i] || '').length
   );
   return result;
}

console.log(romanToInt('IV'));
console.log(romanToInt('MMXIX'));

答案 3 :(得分:0)

试试看。它应该工作:


function conversion(r) {
  const arr = r.split('');
  const val = {
    I: 1,
    V: 5,
    X: 10,
    L: 50,
    C: 100,
    D: 500,
    M: 1000,
  };

  let sum = 0;
  for (let i = 0; i < arr.length; i += 1) {
    if (val[arr[i]] < val[arr[i + 1]]) {
      sum += val[arr[i + 1]] - val[arr[i]];
      i += 1;
    } else {
      sum += val[arr[i]];
    }
  } return sum;
}
      
console.log(conversion("VIII"));
console.log(conversion("LXXIX"));
console.log(conversion("MCMXLIV"));

答案 4 :(得分:0)

罗马到整数 的简短版本:

var romanToInt = (str) => {
  const roman = { I: 1, V: 5, X: 10, L: 50, C: 100, D: 500, M: 1000 };
  let num = 0;
  for (let i = 0; i < str.length; i++) {
    const curr = roman[str[i]];
    const next = roman[str[i + 1]];
    (curr < next) ? (num -= curr) : (num += curr);
  }
  return num;
};

console.log(romanToInt('IV'));
console.log(romanToInt('VIII'));
console.log(romanToInt('LXXIX'));
console.log(romanToInt('MCMXLIV'));


@Jin150Job的另一个独特解决方案

var romanToInt = (str) => {
  const roman = { I: 1, V: 5, X: 10, L: 50, C: 100, D: 500, M: 1000 };
  let num = 0;
  if (str.includes('CM')) num -= 200;
  if (str.includes('CD')) num -= 200;
  if (str.includes('XC')) num -= 20;
  if (str.includes('XL')) num -= 20;
  if (str.includes('IX')) num -= 2;
  if (str.includes('IV')) num -= 2;
  for (var i = 0; i < str.length; i++) {
    num += roman[str[i]];
  }
  return num;
};

console.log(romanToInt('IV'));
console.log(romanToInt('VIII'));
console.log(romanToInt('LXXIX'));
console.log(romanToInt('MCMXLIV'));

答案 5 :(得分:0)

对此解决方案的一个很好且更可取的答案是:

  let roman = "XXI";
  const numeral = {I: 1, V: 5, X: 10, L: 50, C: 100, D: 500, M: 1000};
  let total = 0;
  let current, last = 0;
  roman.split("").reverse().forEach(e => {
    current = numeral[e];
    if (current >= last) {total += current;} else {total -= current;}
    last = current;
  });
  
  return total;

答案 6 :(得分:0)

** 此解决方案适用于每个罗马数字 < 3600

function romanToInt(romeNumStr) {
    const romeMap = {I: 1, V: 5, X: 10, L: 50, C: 100, D: 500, M: 1000};
    let total = 0;
    for (let i=0; i<romeNumStr.length; i++) {
        const chVal = romeMap[romeNumStr[i]];
        let chNextVal
        if (i+1 < romeNumStr.length) {
            // There is more chars
            chNextVal = romeMap[romeNumStr[i+1]];
            if (chVal >= chNextVal) {
                total += chVal;
            } else {
                // Do reverse
                total += chNextVal-chVal
                i+=1
            }
        } else {
            // Last char
            total += chVal;
        }
    }
    return total
}

我的测试:

// TEST
romanToInt('MMMDXCIX')
=3599

答案 7 :(得分:0)

这是另一种求罗马数字整数的方法

function romanToInt(romanNumber) {
   let currentValue = 0;
    let result = 0;
    const string = romanNumber.split('');
    const romanNumbers = {
      I: 1,
      V: 5,
      X: 10,
      L: 50,
      C: 100,
      D: 500,
      M: 1000,
    };
    let firstNum = romanNumbers[string[0].toUpperCase()];
    for (let char of string) {
      currentValue = romanNumbers[char.toUpperCase()];
      if (currentValue <= firstNum) {
        result += currentValue;
      } else {
        result = currentValue - result;
      }
    }
    console.log(`Roman: ${romanNumber}\nInteger: ${result} \n \n`);
    return result;
}

romanToInt('I');
romanToInt('IV');
romanToInt('VI');
romanToInt('IX');
romanToInt('X');
romanToInt('XI');
romanToInt('XII');
romanToInt('XL');
romanToInt('LV');
romanToInt('MMM');
romanToInt('MMC');
romanToInt('MMc');