2016-09-25 39 views
2

我的功能看起来是这样的:罗马来诠释正确转换在某些情况下

let romanToInt = romanNumber => { 
    if(typeof romanNumber !== 'string') throw new TypeError('Argument must be of type String'); 

    const values = { 'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000 }; 
    let sum = 0; 

    romanNumber.split('').map(n => n.toUpperCase()).forEach(n => sum = (sum >= values[n]) ? sum + values[n] : values[n] - sum); 

    return sum; 
} 

console.log(romanToInt("MCMXCVI")); 

大部分我是正确的测试输入,但例如罗马数字MCMXCVI,应该给我1996,而不是2216 ,这正是我所得到的。

我发现了这一点,但我不能确定如何实现:

你必须分开的,几十,几百,数千作为单独 项目。这意味着99是XCIX,90 + 9,但从不应该写为 作为IC。同样,999不能是IM,而1999不能是MIM。

+2

*“这可能与它有关”* - 是的。 CM是900,IX是9,IV是4等等。你的代码根本不允许。 – nnnnnn

+0

@nnnnnn我的文字选择不当。我会编辑,但我仍然不确定如何实现它。 –

+0

@尼古拉斯哈密尔顿错了。用IX试试我的代码。它将打印9. –

回答

1

根据你的问题,你需要迎合单独的项目。一个简单的方法是简单地将值设置得更大,并寻找多个字符匹配。这是可能的,因为只有几个罗马数字允许的组合。我已经把小提琴放在一起here

const values = { 
    'I': 1, 
    'V': 5, 
    'X': 10, 
    'L': 50, 
    'C': 100, 
    'D': 500, 
    'M': 1000, 
    'CM': 900, 
    'CD': 400, 
    'XC': 90, 
    'XL': 40, 
    'IX': 9, 
    'IV': 4 
}; 

let sum = 0; 

while(romanNumber.length > 0){ 
    let piece = romanNumber.substring(0,2); 
    if(values[piece]){ 
    sum += values[piece]; 
    romanNumber = romanNumber.substring(2); 
    }else if(values[piece[0]]){ 
    sum += values[piece[0]]; 
    romanNumber = romanNumber.substring(1); 
    } 
} 

return sum; 
0

您不应该希望用简单的映射来解决问题,因为在罗马数字中,数字的含义取决于上下文。我想,很多情况下可以使用(与分裂和地图,而不是你的线)类似的东西来处理:

var digits = romanNumber.split(''); 
var i = 0; 
while (i < digits.length) { 
    if (i == digits.length - 1 || values[digits[i]] >= values[digits[i+1]]) { 
     sum += values[digits[i]]; 
     i++; 
    } 
    else { 
     sum += values[digits[i+1]] - values[digits[i]]; 
     i += 2; 
    } 
} 

但我不知道它会在所有情况下工作。最好看看它是如何在现成的图书馆中实现的,也许是用于其他语言的。例如,下面是Perl的一个实现:http://search.cpan.org/~chorny/Roman-1.24/lib/Roman.pm

0

我不认为你可以使用单线映射来实现,因为操作取决于相邻字符的比较。然而,用一个简单的循环for

var chars = romanNumber.split(''); 
var sum = values[chars[chars.length - 1]]; 
for (var i = chars.length - 2; i >= 0; i--) { 
    if (values[chars[i + 1]] <= values[chars[i]]) { 
     sum += values[chars[i]]; 
    } else { 
     sum -= values[chars[i]]; 
    } 
} 

的事情是,当一个罗马数字是值比一个其右侧小,你想从和而不是相加的减它。