【发布时间】:2012-02-23 09:04:57
【问题描述】:
如何将整数转换为roman numerals?
function romanNumeralGenerator (int) {
}
例如,请参阅以下示例输入和输出:
1 = "I"
5 = "V"
10 = "X"
20 = "XX"
3999 = "MMMCMXCIX"
警告:仅支持 1 到 3999 之间的数字
【问题讨论】:
如何将整数转换为roman numerals?
function romanNumeralGenerator (int) {
}
例如,请参阅以下示例输入和输出:
1 = "I"
5 = "V"
10 = "X"
20 = "XX"
3999 = "MMMCMXCIX"
警告:仅支持 1 到 3999 之间的数字
【问题讨论】:
const _roman = { M: 1000, CM: 900, D: 500, CD: 400, C: 100, XC: 90, L: 50, XL: 40, X: 10, IX: 9, V: 5, IV: 4, I: 1 };
function toRoman(number = 0) {
return Object.keys(_roman).reduce((acc, key) => {
while (number >= _roman[key]) {
acc += key;
number -= _roman[key];
}
return acc;
}, '');
}
function fromRoman(roman = '') {
return Object.keys(_roman).reduce((acc, key) => {
while (roman.indexOf(key) === 0) {
acc += _roman[key];
roman = roman.substr(key.length);
}
return acc;
}, 0);
}
console.log(toRoman(1903)); // should return 'MCMIII
console.log(fromRoman('MCMIII')); // should return 1903
【讨论】:
var intToRoman = function(value) {
const romanObj = {
1: 'I',
2: 'II',
3: 'III',
4: 'IV',
5: 'V',
6: 'VI',
7: 'VII',
8: 'VIII',
9: 'IX',
10: 'X',
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'
};
let romanValue = '';
while(value>0){
let x = value.toString().length - 1;
let y = x == 0 ? 0 : 10 ** x;
if(!y) { romanValue += romanObj[value], value=0; }
else {
let temp = value % y;
let multiple = Math.floor(value/y);
if (romanObj[multiple*y]) {
romanValue+=romanObj[multiple*y];
} else {
console.log('logger of 1996', romanObj[y], y);
romanValue+=romanObj[y].repeat(multiple);
}
value=temp;
}
}
return romanValue;
}
console.log(intToRoman(18))
【讨论】:
递归,转换前加1,后减1:
const toRoman = (num, i="I", v="V", x="X", l="L", c="C", d="D", m="M") =>
num ? toRoman(num/10|0, x, l, c, d, m, "?", "?", num%=10) +
(i + ["",v,x][++num/5|0] + i.repeat(num%5)).replace(/^(.)(.*)\1/, "$2")
: "";
console.log(toRoman(3999));
【讨论】:
此版本不需要像其他版本那样针对诸如4(IV),9(IX),40(XL),900(CM), etc. 之类的边缘情况进行任何硬编码逻辑。
我已经针对 1-3999 的数据集测试了这段代码,它可以工作。
TLDR;
这也意味着此解决方案可以处理大于最大罗马刻度 (3999) 的数字。
似乎有一个交替规则来决定下一个主要的罗马数字字符。首先乘以 5 得到下一个数字 V,然后乘以 2 得到 X,然后乘以 5 得到 L,然后乘以 2 得到 C,依此类推,得到刻度中的下一个主要数字字符。在这种情况下,让我们假设将“T”添加到比例中以允许比原始罗马比例允许的 3999 更大的数字。为了保持相同的算法,“T”代表 5000。
I = 1
V = I * 5
X = V * 2
L = X * 5
C = L * 2
D = C * 5
M = D * 2
T = M * 5
这可以让我们表示从 4000 到 5000 的数字;例如 MT = 4000。
代码:
function convertToRoman(num) {
//create key:value pairs
var romanLookup = {M:1000, D:500, C:100, L:50, X:10, V:5, I:1};
var roman = [];
var romanKeys = Object.keys(romanLookup);
var curValue;
var index;
var count = 1;
for(var numeral in romanLookup){
curValue = romanLookup[numeral];
index = romanKeys.indexOf(numeral);
while(num >= curValue){
if(count < 4){
//push up to 3 of the same numeral
roman.push(numeral);
} else {
//else we had to push four, so we need to convert the numerals
//to the next highest denomination "coloring-up in poker speak"
//Note: We need to check previous index because it might be part of the current number.
//Example:(9) would attempt (VIIII) so we would need to remove the V as well as the I's
//otherwise removing just the last three III would be incorrect, because the swap
//would give us (VIX) instead of the correct answer (IX)
if(roman.indexOf(romanKeys[index - 1]) > -1){
//remove the previous numeral we worked with
//and everything after it since we will replace them
roman.splice(roman.indexOf(romanKeys[index - 1]));
//push the current numeral and the one that appeared two iterations ago;
//think (IX) where we skip (V)
roman.push(romanKeys[index], romanKeys[index - 2]);
} else {
//else Example:(4) would attemt (IIII) so remove three I's and replace with a V
//to get the correct answer of (IV)
//remove the last 3 numerals which are all the same
roman.splice(-3);
//push the current numeral and the one that appeared right before it; think (IV)
roman.push(romanKeys[index], romanKeys[index - 1]);
}
}
//reduce our number by the value we already converted to a numeral
num -= curValue;
count++;
}
count = 1;
}
return roman.join("");
}
convertToRoman(36);
【讨论】:
婴儿的糖果。
首先,您必须将 romam 映射到对象中的基数:
const _numbersMap = {
M: 1000,
CM: 900,
D: 500,
CD: 400,
C: 100,
XC: 90,
L: 50,
XL: 40,
X: 10,
IX: 9,
V: 5,
IV: 4,
I: 1
}
/* The CM, CD, XC, XL, IX and IV properties are
only needed for the cardinalToRoman() function below. */
注意:如果你只需要将roman转换为cardinal,那么你就不需要上面对象中带有两个romans char的属性了。
然后你构建一个函数来将基数转换为罗马数字:
// The funciton receives a cardinal as parameter (of integer type)
const cardinalToRoman = num => {
// M is the last char in the roman numeric system. Just preventing crashes.
if (num >= 4000) {
console.log('Number is too big');
return
}
let roman = ''; // The initial roman string
// It iterates over the _numbersMap object's properties
for (var i of Object.keys(_numbersMap)) {
/* For each iteration, it will calculate the division of the
given number by the value of the property beeing iterated. */
var q = Math.floor(num / _numbersMap[i]);
/* So the value, multiplied by the current property's value,
will be subtracted from the given number */
num -= q * _numbersMap[i];
/* The result will be the times that the key of the
current property (its respective roman sting) will be repeated
in the final string */
roman += i.repeat(q);
}
return roman;
};
最后,如果你想求逆,然后构建一个函数将罗马转换为基数:
// The funciton receives a roman number as parameter (of srting type)
const romanToCardinal = roman => {
let num = 0; // Initial integer number
/* Let's split the roman string in a Array of chars, and then
put it in reverse order */
const romansArray = Array.from(roman).reverse();
// Then let's iterate the array
romansArray.forEach((char, index, array) => {
/* We take the integer number corresponding to the current
and the previous chars in the iteration. */
const currentNumChar = _numbersMap[char];
const prevNumChar = _numbersMap[array[index - 1]];
// Throws error if the char is unknown.
if (!currentNumChar) {
console.error(`The charecter "${char}" of the given roman number "${roman}" is invalid as a roman number char.`);
return false;
}
/* The integer corresponding to the current char is
subtracted from the result if it's bigger than the previous
integer. If itsn't, the integer is summed to the result */
if (prevNumChar && prevNumChar > currentNumChar) {
num -= currentNumChar;
} else {
num += currentNumChar;
}
});
return num;
}
试试JSFiddle。
【讨论】:
它从 1 到 9999 有效。如果有一个 10000 的罗马数字,只需将其替换为罗马数字并创建另一个 99999 的限制。
function convertToRoman(num) {
const numArray = num.toString().split("")
const roman = {
1: "I",
5: 'V',
10: 'X',
50: 'L',
100: 'C',
500: "D",
1000: 'M',
9999: "LIMIT"
}
let numLen = numArray.length;
let converted = numArray.map((x) => {
numLen--;
return x + "0".repeat(numLen)
})
let trans = converted.map((x) => {
let last = "";
for (let key in roman) {
if (x.charAt(0) == 0) {
return ""
}
if (key == x) {
return roman[key];
}
if (key > parseInt(x) && last < parseInt(x)) {
if (last.length == key.length) {
const ave = (parseInt(last) + parseInt(key)) / 2
if (x > ave) {
return roman[last] + roman[key]
}
return roman[last].repeat(x.charAt(0));
}
if (x.charAt(0) == 9) {
return roman[key.slice(0, key.length - 1)] + roman[key];
}
return roman[last] + roman[key.slice(0, key.length - 1)].repeat(x.charAt(0) - 5)
}
last = key
}
})
return trans.join("");
}
for(let i = 1; i < 12; i++) {
console.log(i, "->", convertToRoman(i))
}
【讨论】:
如果有人需要,只是添加大数字
function convertToRoman(num) {
if (num < 1 ) {
console.error('Error (fn convertToRoman(num)): Can\'t convert negetive numbers. You provided: ' + num);
return false;
}
if (+num > 3000000) {
console.error('Error (fn convertToRoman(num)): Can\'t convert numbers greater than 3000000. You provided: ' + num);
return false;
}
if (!+num) {
console.error('Error (fn convertToRoman(num)): \'num\' must be a number or number in a string. You provided: ' + num);
return false;
}
function num2let(a, b, c, num) {
if(num < 4) return a.repeat(num);
else if (num === 4) return a + b;
else if (num < 9) return b + a.repeat(num - 5);
else return a + c;
}
let romanArray = ["I", "V", "X", "L", "C", "D", "M", "Vb", "Xb", "Lb", "Cb", "Db", "Mb"]; // Xb means Xbar
let arr = String(+num).split('').map(el => +el);
let len = arr.length;
let roman = "";
arr.forEach(el => {
let index = (len - 1) * 2;
roman += num2let(romanArray[index], romanArray[index + 1], romanArray[index + 2], el);
len--;
});
return roman;
}
【讨论】:
给你。
function check(digit, char1, char2, char3) {
if(digit <=3) {
return char1.repeat(digit)
}if(digit == 4){
return char1+char2
}if(digit == 5) {
return char2
}if (digit > 5 && digit < 9) {
return char2+char1.repeat(digit-5)
}if(digit == 9) {
return char1+char3
}
}
function convertToRoman(num) {
let result;
let numList = String(num).split("").reverse()
result = [check(parseInt(numList[0]), 'I', 'V', 'X'),check(parseInt(numList[1]), 'X', 'L', 'C'),check(parseInt(numList[2]), 'C', 'D', 'M'),'M'.repeat(parseInt(numList[3]))]
return result.reverse().join('');
}
let res = convertToRoman(2);
console.log(res)
【讨论】:
function convertToRoman(num: number){
let integerToRomanMap = new Map<number, string>([
[1000, "M"], [900, "CM"], [800, "DCCC"], [700, "DCC"], [600, "DC"],
[500, "D"], [400, "CD"], [300, "CCC"], [200, "CC"],
[100, "C"], [90, "XC"], [80, "LXXX"], [70, "LXX"], [60, "LX"],
[50, "L"], [40, "XL"], [30, "XXX"], [20, "XX"],
[10, "X"], [9, "IX"], [8, "VIII"], [7, "VII"], [6, "VI"],
[5, "V"], [4, "IV"], [3, "III"], [2, "II"], [1, "I"]
])
if(integerToRomanMap.has(num)){
return integerToRomanMap.get(num)
}
let res = ''
while(num > 0){
let len = String(num).length;
let divisor = Math.pow(10, len - 1)
let quotient = Math.floor(num/divisor)
num = num % divisor
if(integerToRomanMap.has(divisor * quotient)){
res += integerToRomanMap.get(divisor * quotient)
}else{
while(quotient > 0){
res += integerToRomanMap.get(divisor)
quotient--;
}
}
}
return res;
}
【讨论】:
如果HTMLElement中有这个数字(如span),建议添加HTML属性 data-format :
Number.prototype.toRoman = function() {
var e = Math.floor(this),
t, n = "",
i = 3999,
s = 0;
v = [1e3, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1], r = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"];
if (e < 1 || e > i) return "";
while (s < 13) {
t = v[s];
while (e >= t) {
e -= t;
n += r[s]
}
if (e == 0) return n;
++s
}
return ""
};
var fnrom = function(e) {
if (parseInt(e.innerHTML)) {
e.innerHTML = parseInt(e.innerHTML).toRoman()
}
};
setTimeout(function() {
[].forEach.call(document.querySelectorAll("[data-format=roman]"), fnrom)
}, 10)
Phase <span data-format="roman">4</span> Sales
【讨论】:
function convertToRoman(num) {
let I = 1
let IV = 4
let V = 5
let IX = 9
let X = 10
let XL = 40
let L = 50
let XC = 90
let C = 100
let CD = 400
let D = 500
let CM = 900
let M = 1000
let arr = []
while(num > 0) {
console.log(num)
switch(true) {
case num - M >= 0 :
arr.push('M')
num -= M
break
case num - CM >= 0 :
arr.push('CM')
num -= CM
break
case num - D >= 0 :
arr.push('D')
num -= D
break
case num - CD >= 0 :
arr.push('CD')
num -= CD
break
case num - C >= 0 :
arr.push('C')
num -= C
break
case num - XC >= 0 :
arr.push('XC')
num -= XC
break
case num - L >= 0 :
arr.push('L')
num -= L
break
case num - XL >= 0 :
arr.push('XL')
num -= XL
break
case num - X >= 0 :
arr.push('X')
num -= X
break
case num - IX >= 0 :
arr.push('IX')
num -= IX
break
case num - V >= 0 :
arr.push('V')
num -= V
break
case num - IV >= 0 :
arr.push('IV')
num -= IV
break
case (num - I) >= 0 :
arr.push('I')
num -= I
break
}
}
str = arr.join("")
return str
}
【讨论】:
字符串方式: (适用于 M chiffer 及以下)
const romanNumerals = [
['I', 'V', 'X'],//for ones 0-9
['X', 'L', 'C'],//for tens 10-90
['C', 'D', 'M'] //for hundreds 100-900
];
function romanNumUnderThousand(dijit, position) {
let val = '';
if (position < 3) {
const [a, b, c] = romanNumerals[position];
switch (dijit) {
case '1': val = a; break;
case '2': val = a + a; break;
case '3': val = a + a + a; break;
case '4': val = a + b; break;
case '5': val = b; break;
case '6': val = b + a; break;
case '7': val = b + a + a; break;
case '8': val = b + a + a + a; break;
case '9': val = a + c; break;
}
}
return val;
}
function convertToRoman(num) {
num = parseInt(num);
const str_num = num.toString();
const lastIndex = str_num.length - 1;
return [
`${(num > 999) ? 'M'.repeat(parseInt(str_num.slice(0, lastIndex - 2))) : ''}`,
`${(num > 99) ? romanNumUnderThousand(str_num[lastIndex - 2], 2) : ''}`,
`${(num > 9) ? romanNumUnderThousand(str_num[lastIndex - 1], 1) : ''}`,
romanNumUnderThousand(str_num[lastIndex], 0)
].join('');
}
convertToRoman(36);
【讨论】:
这是递归的解决方案,看起来很简单:
const toRoman = (num, result = '') => {
const map = {
M: 1000,
CM: 900,
D: 500,
CD: 400,
C: 100,
XC: 90,
L: 50,
XL: 40,
X: 10,
IX: 9,
V: 5,
IV: 4,
I: 1,
};
for (const key in map) {
if (num >= map[key]) {
if (num !== 0) {
return toRoman(num - map[key], result + key);
}
}
}
return result;
};
console.log(toRoman(402)); // CDII
console.log(toRoman(3000)); // MMM
console.log(toRoman(93)); // XCIII
console.log(toRoman(4)); // IV
【讨论】:
这是我的;
function convertToRoman(num) {
let decimalValueArray = [1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000, "bigger"];
let romanNumArray = ["I", "IV", "V", "IX", "X", "XL", "L", "XC", "C", "CD", "D", "CM", "M"];
let resultNumArray = [];
function getRoman(num) {
for (let i = 0; i < decimalValueArray.length; i++) {
let decimalElem = decimalValueArray[i];
if (num === decimalElem || num === 0) {
resultNumArray.push(romanNumArray[i]);
return ;
} else if (decimalElem > num || decimalElem === "bigger") { //using (decimalElem>num) and then array value of(i-1) to get the highest decimal value from the array.but this doesnt work when highest decimel value is 1000.so added "bigger" element.
resultNumArray.push(romanNumArray[i - 1]);
getRoman(num - (decimalValueArray[i - 1]));
} else {
continue;
}
return;
}
}
getRoman(num);
let resultNumber = (resultNumArray.join(""));
return(resultNumber); }
【讨论】:
function atalakit (num) {
var result ="";
var roman = ["MMM", "MM", "M", "CM", "DCCC", "DCC", "DC", "D", "CD", "CCC", "CC", "C", "XC", "LXXX", "LXX", "LX", "L", "XL", "XXX", "XX", "XI", "X", "IX", "VIII", "VII", "VI", "V", "IV", "III", "II", "I"];
var arabic = [3000, 2000, 1000, 900, 800, 700, 600, 500, 400, 300, 200, 100, 90, 80, 70, 60, 50, 40, 30, 20, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1];
if ( num>0 && num<4000) {
var arabiclength = arabic.length;
for ( i=0; arabiclength > i; i++) {
if (Math.floor(num/arabic[i])>0){
result += roman[i];
num -= arabic[i];
}
}
}
else {
document.getElementById('text').innerHTML = "too much";
}
document.getElementById('text2').innerHTML = result;
}
【讨论】:
很好的回应。您可以通过编程方式完成此操作,而无需对这些值进行过多的硬编码。只是你的代码会长一点。
const convertToRoman = (arabicNum) => {
const roman_benchmarks = {1: 'I', 5: 'V', 10: 'X', 50: 'L', 100: 'C', 500: 'D', 1000: 'M', 5000: '_V', 10000: '_X', 50000: '_L', 100000: '_C'};
// in the future, you can add higher numbers with their corresponding roman symbols/letters and the program will adjust to the change
const arabic_benchmarks = [1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 50000, 100000]; // don't forget to include the new numbers here too
arabicNum = parseInt(arabicNum);
let proceed = parseInt(arabicNum.toString().length);
let romanNumeral = '';
while(proceed){ // the loop continues as long as there's still a unit left in arabicNum
const temp_denominator = 1 * (10**(arabicNum.toString().length-1)); // determine what multiple of 10 arabicNum is
const multiple = Math.floor(arabicNum/temp_denominator); // get its first digit
const newNum = multiple*temp_denominator; // regenerate a floored version of arabicNum
const filtered_two = arabic_benchmarks.filter((x, i) => newNum >= x && newNum<= arabic_benchmarks[i+1] || newNum <= x && newNum>= arabic_benchmarks[i-1]);
// filter arabic_benchmarks for the 2 boundary numbers newNum falls within
switch (newNum) { // check for what roman numeral best describes newNum and assign it to romanNumeral
case (newNum == filtered_two[0]-temp_denominator ? newNum :''):
romanNumeral += roman_benchmarks[temp_denominator]+roman_benchmarks[filtered_two[0]]
break;
case (newNum == filtered_two[0] ? newNum : ''):
romanNumeral += roman_benchmarks[filtered_two[0]]
break;
case (newNum > filtered_two[0] && newNum < (filtered_two[1]-temp_denominator) ? newNum : ''):
romanNumeral += roman_benchmarks[filtered_two[0]]
const factor = multiple < 5 ? (multiple%5)-1 : multiple%5;
for(let i = 0; i < factor; i++){
romanNumeral += roman_benchmarks[temp_denominator];
}
break;
case (newNum == filtered_two[1]-temp_denominator ? newNum : ''):
romanNumeral += roman_benchmarks[temp_denominator]+roman_benchmarks[filtered_two[1]];
break;
case (newNum == filtered_two[1] ? newNum : ''):
romanNumeral += roman_benchmarks[filtered_two[1]];
break;
default:
break;
}
arabicNum = arabicNum - newNum; // reduce arabicNum by its first hierarchy
proceed--; // continue the loop
}
return romanNumeral;
}
【讨论】:
使用此代码:
function convertNumToRoman(num){
const romanLookUp = {M:1000, CM:900,D:500,CD:400,C:100,XC:90,L:50,XL:40,X:10,IX:9,V:5,IV:4,I:1}
let result = ''
// Sort the object values to get them to descending order
Object.keys(romanLookUp).sort((a,b)=>romanLookUp[b]-romanLookUp[a]).forEach((key)=>{
while(num>=romanLookUp[key]){
result+=key;
num-=romanLookUp[key]
}
})
return result;
}
【讨论】:
这是我的解决方案:
var roman = "MX";
function solution(roman) {
var val = 0;
for (let i = 0; i < roman.length; i++) {
if (roman.charAt(i) == 'I') {
if (roman.charAt(i + 1) == 'V') {
val += 4; // IV
} else if (roman.charAt(i + 1) == 'X') {
val += 9; // IX
} else {
val += 1; // I
}
} else if (roman.charAt(i) == 'V') {
if (roman.charAt(i - 1) == 'I') {
val = val;
} else {
val += 5; // V
}
} else if (roman.charAt(i) == 'X') {
if (roman.charAt(i - 1) == 'I') { // Check if there is I before X
val = val;
}else if (roman.charAt(i + 1) == 'L') {
val += 40; // XL
} else if (roman.charAt(i + 1) == 'C') {
val += 90; // XC
} else {
val += 10; // X
}
} else if (roman.charAt(i) == 'L') {
if (roman.charAt(i - 1) == 'X') { // Check if there is X before L
val = val;
} else {
val += 50; // L
}
} else if (roman.charAt(i) == 'C') {
if (roman.charAt(i - 1) == 'X') {
val = val; // XC
}else if (roman.charAt(i + 1) == 'D') {
val += 400; // CD
} else if (roman.charAt(i + 1) == 'M') {
val += 900; // CM
} else {
val += 100; // C
}
} else if (roman.charAt(i) == 'D') {
if (roman.charAt(i - 1) == 'C') {
val = val; // CD
} else {
val += 500; // D
}
} else if (roman.charAt(i) == 'M') {
if (roman.charAt(i - 1) == 'C') {
val = val; // CM
} else {
val += 1000; // M
}
}
}
return val;
}
console.log(solution(roman)); // The answer is: 1010
【讨论】:
var romanToInt = function(s) {
var sum = [];
var obj = {"I":1,"V":5,"X":10,"L":50,"C":100,"D":500,"M":1000};
for(var i=0;i<s.length;i++){
if(obj[s[i]]>obj[s[i-1]]){
sum[i-1] = (obj[s[i]]-obj[s[i-1]])
}else{
sum[i]=(obj[s[i]])
}
}
return sum.reduce((a, b) => a + b, 0);
};
上面的代码使用一个对象来查找值并进行相应的计算。
var romanToInt = function(s) {
var sum = [];
for(var i=0;i<s.length;i++){
if(s[i]=="I"){
sum.push(1);
}else if(s[i]=="V"){
sum.push(5);
}else if(s[i]=="X"){
sum.push(10);
}else if(s[i]=="L"){
sum.push(50);
}else if(s[i]=="C"){
sum.push(100);
}else if(s[i]=="D"){
sum.push(500);
}else if(s[i]=="M"){
sum.push(1000);
}
if(sum[i-1]<sum[i]){
sum[i] = sum[i]-sum[i-1]
sum[i-1] = 0
}else{
sum[i] = sum[i]
}
}
return sum.reduce((a, b) => a + b, 0)
};
上述案例中的代码使用 if/else-if 语句来执行相同的操作。此方法执行速度更快,内存效率也很高。
用switch语句也可以通过以下方式解决。
var romanToInt = function(s) {
var sum = [];
for(var i=0;i<s.length;i++){
switch(s[i]){
case "I":
sum.push(1);
break;
case "V":
sum.push(5);
break;
case "X":
sum.push(10);
break;
case "L":
sum.push(50);
break;
case "C":
sum.push(100);
break;
case "D":
sum.push(500);
break;
case "M":
sum.push(1000);
break;
}
if(sum[i-1]<sum[i]){
sum[i] = sum[i]-sum[i-1]
sum[i-1] = 0
}else{
sum[i] = sum[i]
}
}
return sum.reduce((a, b) => a + b, 0)
};
【讨论】:
我还没有看到这个帖子,所以这是一个仅使用字符串操作的有趣解决方案:
var numbers = [1, 4, 5, 7, 9, 14, 15, 19, 20, 44, 50, 94, 100, 444, 500, 659, 999, 1000, 1024];
var romanNumeralGenerator = function (number) {
return 'I'
.repeat(number)
.replace(/I{5}/g, 'V')
.replace(/V{2}/g, 'X')
.replace(/X{5}/g, 'L')
.replace(/L{2}/g, 'C')
.replace(/C{5}/g, 'D')
.replace(/D{2}/g, 'M')
.replace(/DC{4}/g, 'CM')
.replace(/C{4}/g, 'CD')
.replace(/LX{4}/g, 'XC')
.replace(/X{4}/g, 'XL')
.replace(/VI{4}/g, 'IX')
.replace(/I{4}/g, 'IV')
};
console.log(numbers.map(romanNumeralGenerator))
【讨论】:
const convertToRoman = (n)=>
{
let u =0;
let result ='';
let rL='IVXLCDM';
while (n>0)
{
u=n%10;
switch (u){
case 1: result = rL[0] + result ;
break;
case 2: result = rL[0]+rL[0] + result;
break;
case 3: result = rL[0]+rL[0]+rL[0] + result;
break;
case 4: result = rL[0]+rL[1] + result;
break;
case 5: result = rL[1] + result;
break;
case 6: result = rL[1] + rL[0] + result;
break;
case 7: result =rL[1] + rL[0] +rL[0] + result;
break;
case 8: result = rL[1] + rL[0] +rL[0] + rL[0] + result;
break;
case 9: result = rL[0] + rL[2] + result;
break;
};
rL = rL.substring(2)
// after every last digit.. when conversion is finished..
// number is taking another value - same as container with roman Letter
n=Math.trunc(n/10);
};
return result;
};
我是初学者,我看到这样 ))) 没有数组。当然,在函数中使用 itter + acc 会更好.. 刚刚通过freeCodeCamp的测试
【讨论】:
const basicRomanNumeral =
['',
'I','II','III','IV','V','VI','VII','VIII','IX','',
'X','XX','XXX','XL','L','LX','LXX','LXXX','XC','',
'C','CC','CCC','CD','D','DC','DCC','DCCC','CM','',
'M','MM','MMM'
];
function convertToRoman(num) {
const numArray = num.toString().split('');
const base = numArray.length;
let count = base-1;
const convertedRoman = numArray.reduce((roman, digit) => {
const digitRoman = basicRomanNumeral[+digit + count*10];
const result = roman + digitRoman;
count -= 1;
return result;
},'');
return convertedRoman;
}
【讨论】:
循环可能更优雅,但我发现它们很难阅读。想出了一个或多或少的硬编码版本,看起来很容易。只要你理解了第一行,剩下的就很容易了。
function romanNumeralGenerator (int) {
let roman = '';
roman += 'M'.repeat(int / 1000); int %= 1000;
roman += 'CM'.repeat(int / 900); int %= 900;
roman += 'D'.repeat(int / 500); int %= 500;
roman += 'CD'.repeat(int / 400); int %= 400;
roman += 'C'.repeat(int / 100); int %= 100;
roman += 'XC'.repeat(int / 90); int %= 90;
roman += 'L'.repeat(int / 50); int %= 50;
roman += 'XL'.repeat(int / 40); int %= 40;
roman += 'X'.repeat(int / 10); int %= 10;
roman += 'IX'.repeat(int / 9); int %= 9;
roman += 'V'.repeat(int / 5); int %= 5;
roman += 'IV'.repeat(int / 4); int %= 4;
roman += 'I'.repeat(int);
return roman;
}
【讨论】:
此解决方案只运行一个循环,并且具有将数字映射为罗马字母的最小对象
function RomantoNumeral(r){
let result = 0,
keys = {M:1000, D:500, C:100, L:50, C:100, L:50, X:10, V:5, I:1},
order = Object.keys(keys),
rom = Array.from(r)
rom.forEach((e, i)=>{
if( i < rom.length -1 && order.indexOf(e) > order.indexOf(rom[i+1])){
result -= keys[e]
} else {
result +=keys[e]
}
})
return result
}
RomantoNumeral('MMDCCCXXXVII') #2837
【讨论】:
function convertToRoman(num) {
var roman = {
M: 1000,
CM: 900,
D: 500,
CD: 400,
C: 100,
XC: 90,
L: 50,
XL: 40,
X: 10,
IX: 9,
V: 5,
IV: 4,
I: 1
}
var result = '';
for (var key in roman) {
if (num == roman[key]) {
return result +=key;
}
var check = num > roman[key];
if(check) {
result = result + key.repeat(parseInt(num/roman[key]));
num = num%roman[key];
}
}
return result;
}
console.log(convertToRoman(36));
【讨论】:
这是我的单循环解决方案
function convertToRoman(num) {
var roman = {
M: 1000,
CM: 900,
D: 500,
CD: 400,
C: 100,
XC: 90,
L: 50,
XL: 40,
X: 10,
IX: 9,
V: 5,
IV: 4,
I: 1
};
var romanNum = "";
for(key in roman){
var check = num>=roman[key];
if(check){
console.log(romanNum);
romanNum += key;
num-= roman[key];
}
}
return romanNum
}
convertToRoman(150);
【讨论】:
这是我的代码,希望对您有所帮助:
function convertToRoman(num) {
let numArr = [];//[M,D,C,L,X,V,I]
let numStr = "";
//get num Array
numArr.push(parseInt(num / 1000));
num %= 1000;
numArr.push(parseInt(num / 500));
num %= 500;
numArr.push(parseInt(num / 100));
num %= 100;
numArr.push(parseInt(num / 50));
num %= 50;
numArr.push(parseInt(num / 10));
num %= 10;
numArr.push(parseInt(num / 5));
num %= 5;
numArr.push(num);
//cancat num String
for(let i = 0; i < numArr.length; i++) {
switch(i) {
case 0://M
for(let j = 0; j < numArr[i]; j++) {
numStr = numStr.concat("M");
}
break;
case 1://D
switch(numArr[i]) {
case 0:
break;
case 1:
if(numArr[i + 1] === 4) {
numStr = numStr.concat("CM");
i++;
}else {
numStr = numStr.concat("D");
}
break;
}
break;
case 2://C
switch(numArr[i]) {
case 0:
break;
case 1:
numStr = numStr.concat("C");
break;
case 2:
numStr = numStr.concat("CC");
break;
case 3:
numStr = numStr.concat("CCC");
break;
case 4:
numStr = numStr.concat("CD");
break;
}
break;
case 3://L
switch(numArr[i]) {
case 0:
break;
case 1:
if(numArr[i + 1] === 4) {
numStr = numStr.concat("XC");
i++;
}else {
numStr = numStr.concat("L");
}
break;
}
break;
case 4://X
switch(numArr[i]) {
case 0:
break;
case 1:
numStr = numStr.concat("X");
break;
case 2:
numStr = numStr.concat("XX");
break;
case 3:
numStr = numStr.concat("XXX");
break;
case 4:
numStr = numStr.concat("XL");
break;
}
break;
case 5://V
switch(numArr[i]) {
case 0:
break;
case 1:
if(numArr[i + 1] === 4) {
numStr = numStr.concat("IX");
i++;
}else {
numStr = numStr.concat("V");
}
break;
}
break;
case 6://I
switch(numArr[i]) {
case 0:
break;
case 1:
numStr = numStr.concat("I");
break;
case 2:
numStr = numStr.concat("II");
break;
case 3:
numStr = numStr.concat("III");
break;
case 4:
numStr = numStr.concat("IV");
break;
}
break;
}
}
console.log(numStr);
return numStr;
}
convertToRoman(3999);
【讨论】:
我真的很喜欢 jaggedsoft 的解决方案,但我无法回复,因为我的代表太低了 :( :(
我将它分解为那些不理解它的人解释一下。希望它可以帮助某人。
function convertToRoman(num) {
var lookup =
{M:1000,CM:900,D:500,CD:400,C:100,XC:90,L:50,XL:40,X:10,IX:9,V:5,IV:4,I:1},roman = '',i;
for ( i in lookup ) {
while ( num >= lookup[i] ) { //while input is BIGGGER than lookup #..1000, 900, 500, etc.
roman += i; //roman is set to whatever i is (M, CM, D, CD...)
num -= lookup[i]; //takes away the first num it hits that is less than the input
//in this case, it found X:10, added X to roman, then took away 10 from input
//input lowered to 26, X added to roman, repeats and chips away at input number
//repeats until num gets down to 0. This triggers 'while' loop to stop.
}
}
return roman;
}
console.log(convertToRoman(36));
【讨论】:
可能是最简单的解决方案:
rome = n => {
b=0
s=''
for(a=5; n; b++,a^=7)
for(o=n%a, n=n/a^0;o--;)
s='IVXLCDM'[o>2?b+n-(n&=-2)+(o=1):b]+s
return s
}
r = [rome(892),rome(3999)];
console.log(r);
但我不能相信。这是 CodeSignal 上的vetalperko's 解决方案。
【讨论】:
我用谷歌在这个博客上找到了一个不错的:
http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter
function romanize (num) {
if (isNaN(num))
return NaN;
var digits = String(+num).split(""),
key = ["","C","CC","CCC","CD","D","DC","DCC","DCCC","CM",
"","X","XX","XXX","XL","L","LX","LXX","LXXX","XC",
"","I","II","III","IV","V","VI","VII","VIII","IX"],
roman = "",
i = 3;
while (i--)
roman = (key[+digits.pop() + (i * 10)] || "") + roman;
return Array(+digits.join("") + 1).join("M") + roman;
}
【讨论】:
NaN 或 throw 而不是返回 false,如该帖子中所述。
715799999999 (715,799,999,999)。较大的数字要么不返回任何内容,要么(对于非常大的数字)输出RangeError: Invalid array length 错误。否则,它可以完美运行。谢谢!