note для пользователей php 7, добавьте это в свой файл httpd.conf:
# PHP 7 specific configuration
<IfModule php7_module>
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps
<IfModule dir_module>
DirectoryIndex index.html index.php
</IfModule>
</IfModule>
Ну, похоже, я не единственный, кто застрял в этой проблеме на FreeCodeCamp. Но я хотел бы поделиться своим кодом с вами в любом случае. Это довольно впечатляюще, почти на 10% быстрее, чем топ-голосованное решение здесь (я не тестировал все остальные, и я думаю, что мой не самый быстрый). Но я думаю, что это чисто и легко понять:
function convertToRoman(num) {
// Some error checking first
if (+num > 9999) {
console.error('Error (fn convertToRoman(num)): Can\'t convert numbers greater than 9999. 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;
}
// Convert the number into
// an array of the numbers
var arr = String(+num).split('').map((el) => +el );
// Keys to the roman numbers
var keys = {
1: ['', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX'],
2: ['', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC'],
3: ['', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM'],
4: ['', 'M', 'MM', 'MMM', 'MMMM', 'MMMMM', 'MMMMMM', 'MMMMMMM', 'MMMMMMMM', 'MMMMMMMMM'],
};
// Variables to help building the roman string
var i = arr.length;
var roman = '';
// Iterate over each number in the array and
// build the string with the corresponding
// roman numeral
arr.forEach(function (el) {
roman += keys[i][el];
i--;
});
// Return the string
return roman;
}
Это может показаться ограничением, что он может конвертировать только числа до 9 999. Но дело в том, что от 10 000 и выше строка должна быть выше над литералами. И что я еще не решил.
Надеюсь, это вам поможет.
Я не понимаю, почему все решения так длинны и использует несколько циклов.
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 str = "";
for (var i of Object.keys(roman) ) {
var q = Math.floor(num / roman[i]);
num -= q * roman[i];
str += i.repeat(q);
}
return str;
}
Я лично считаю, что самый аккуратный способ (а не самый быстрый) - с рекурсией.
function convert(num) {
if(num < 1){ return "";}
if(num >= 40){ return "XL" + convert(num - 40);}
if(num >= 10){ return "X" + convert(num - 10);}
if(num >= 9){ return "IX" + convert(num - 9);}
if(num >= 5){ return "V" + convert(num - 5);}
if(num >= 4){ return "IV" + convert(num - 4);}
if(num >= 1){ return "I" + convert(num - 1);}
}
console.log(convert(39));
//Output: XXXIX
Это будет поддерживать только числа 1-40, но его можно легко расширить, следуя шаблону.
Это работает для всех чисел, которые нуждаются только в римских цифрах M и ниже.
function convert(num) {
var code = [
[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"],
];
var rom = "";
for(var i=0; i<code.length; i++) {
while(num >= code[i][0]) {
rom += code[i][1];
num -= code[i][0];
}
}
return rom;
}
Я просто сделал это на freecodecamp. Его можно легко расширить.
function convertToRoman(num) {
var roman ="";
var values = [1000,900,500,400,100,90,50,40,10,9,5,4,1];
var literals = ["M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"];
for(i=0;i<values.length;i++){
if(num>=values[i]){
if(5<=num && num<=8) num -= 5;
else if(1<=num && num<=3) num -= 1;
else num -= values[i];
roman += literals[i];
i--;
}
}
return roman;
}
После тестирования некоторых реализаций в этом сообщении я создал новую оптимизированную для более быстрого выполнения. Исполнение времени действительно низкое по сравнению с другими, но, очевидно, код уродливый :). Это может быть еще быстрее с индексированным массивом со всеми возможностями. На всякий случай это помогает кому-то.
function concatNumLetters(letter, num) {
var text = "";
for(var i=0; i<num; i++){
text += letter;
}
return text;
}
function arabicToRomanNumber(arabic) {
arabic = parseInt(arabic);
var roman = "";
if (arabic >= 1000) {
var thousands = ~~(arabic / 1000);
roman = concatNumLetters("M", thousands);
arabic -= thousands * 1000;
}
if (arabic >= 900) {
roman += "CM";
arabic -= 900;
}
if (arabic >= 500) {
roman += "D";
arabic -= 500;
}
if (arabic >= 400) {
roman += "CD";
arabic -= 400;
}
if (arabic >= 100) {
var hundreds = ~~(arabic / 100);
roman += concatNumLetters("C", hundreds);
arabic -= hundreds * 100;
}
if (arabic >= 90) {
roman += "XC";
arabic -= 90;
}
if (arabic >= 50) {
roman += "L";
arabic -= 50;
}
if (arabic >= 40) {
roman += "XL";
arabic -= 40;
}
if (arabic >= 10) {
var dozens = ~~(arabic / 10);
roman += concatNumLetters("X", dozens);
arabic -= dozens * 10;
}
if (arabic >= 9) {
roman += "IX";
arabic -= 9;
}
if (arabic >= 5) {
roman += "V";
arabic -= 5;
}
if (arabic >= 4) {
roman += "IV";
arabic -= 4;
}
if (arabic >= 1) {
roman += concatNumLetters("I", arabic);
}
return roman;
}
Я знаю, что это старый вопрос, но я очень горжусь этим решением :) Он обрабатывает номера меньше 1000, но его можно легко расширить, включив в него как можно больший объем, добавив в 2D-код numeralCodes массив.
var numeralCodes = [["","I","II","III","IV","V","VI","VII","VIII","IX"], // Ones
["","X","XX","XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"], // Tens
["","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"]]; // Hundreds
function convert(num) {
var numeral = "";
var digits = num.toString().split('').reverse();
for (var i=0; i < digits.length; i++){
numeral = numeralCodes[i][parseInt(digits[i])] + numeral;
}
return numeral;
}
<input id="text-input" type="text">
<button id="convert-button" onClick="var n = parseInt(document.getElementById('text-input').value);document.getElementById('text-output').value = convert(n);">Convert!</button>
<input id="text-output" style="display:block" type="text">
Я создал два сдвоенных массива, один с арабскими числами, другой с римскими символами.
function convert(num) {
var result = '';
var rom = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'];
var ara = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
Затем я добавил цикл, который сканирует римские элементы, добавив, что наибольший по-прежнему состоит из NUM для РЕЗУЛЬТАТОВ, тогда мы уменьшаем NUM той же суммы.
Это похоже на то, что мы отображаем часть NUM в римских числах, а затем уменьшаем ее на ту же сумму.
for (var x = 0; x < rom.length; x++) {
while (num >= ara[x]) {
result += rom[x];
num -= ara[x];
}
}
return result;
}
Вот решение регулярного выражения:
function deromanize(roman) {
var r = 0;
// regular expressions to check if valid Roman Number.
if (!/^M*(?:D?C{0,3}|C[MD])(?:L?X{0,3}|X[CL])(?:V?I{0,3}|I[XV])$/.test(roman))
throw new Error('Invalid Roman Numeral.');
roman.replace(/[MDLV]|C[MD]?|X[CL]?|I[XV]?/g, function(i) {
r += {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}[i];
});
return r;
}
function convertToRoman (num) {
var v = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
var r = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'];
var s = "";
for(i = 0; i < v.length; i++) {
value = parseInt(num/v[i]);
for(j = 0; j < value; j++) {
s += r[i];
}
num = num%v[i];
}
return s;
}
Мое решение разбивает число на массив строк, добавляет нули к каждому элементу на основе его позиции относительно длины массива, преобразует новые строки с нулями в римские цифры и затем объединяет их вместе. Это будет работать только с номерами до 3999:
function convertToRoman(num){
var rnumerals = { 1 : 'I', 2 : 'II', 3 : 'III', 4 : 'IV', 5 : 'V', 6 : 'VI', 7 : 'VII',
8 : 'VIII', 9 : 'IX', 10 : 'X', 20 : 'XX', 30 : 'XXX', 40 : 'XL', 50 : 'L',
60 : 'LX', 70 : 'LXX', 80 : 'LXXX', 90 : 'XC', 100 : 'C', 200 : 'CC', 300 : 'CCC',
400 : 'CD', 500 : 'D', 600 : 'DC', 700 : 'DCC', 800 : 'DCCC', 900 : 'CM',
1000: 'M', 2000: 'MM', 3000: 'MMM'};
var zeros, romNum;
var arr = num.toString().split("");
var romArr = [];
for(var i=0; i < arr.length; i++){
zeros = "0".repeat((arr.length - i - 1));
arr[i] = arr[i].concat(zeros);
romArr.push(rnumerals[(arr[i])]);
}
romNum = romArr.join('');
return romNum;
}
var romanNumerals = [
['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]];
RomanNumerals = {
romerate: function(foo) {
var bar = '';
romanNumerals.forEach(function(buzz) {
while (foo >= buzz[1]) {
bar += buzz[0];
foo -= buzz[1];
}
});
return bar;
},
numerate: function(x) {
var y = 0;
romanNumerals.forEach(function(z) {
while (x.substr(0, z[0].length) == z[0]) {
x = x.substr(z[0].length);
y += z[1];
}
});
return y;
}
};
ЕСЛИ это число в HTMLElement (например, span), мы рекомендуем добавить атрибут HTML data-format
:
<p>Phase <span data-format="roman">4 </span> Sales</p>
Примечание. Это не стандарт html. Используемый код Javascript отображается после прокрутки вниз в разделе html на jsfiddle.
for...in
.
– Oriol
31 July 2016 в 22:01
Если вы хотите преобразовать большое число с большим количеством символов, возможно, этот алго мог бы помочь.
Единственная предпосылка для символов - это то, что должно быть нечетным и следовать одному правилу (1, 5, 10, 50,100 ...., 10 ^ (N) / 2, 10 ^ (N)).
var rnumbers = ["I","V","X","L","C","D","M"];
rnumbers = rnumbers.concat(["V","X","L","C","D","M"].map(function(n) {return '<span style="border-top:1px solid black; padding:1px;">'+n+'</span> '}));
rnumbers = rnumbers.concat(["V","X","L","C","D","M"].map(function(n) {return '<span style="border:1px solid black; border-bottom:1px none black; padding:1px;">'+n+'</span> '}));
rnumbers = rnumbers.concat(["V","X","L","C","D","M"].map(function(n) {return '<span style="border-top:3px double black; padding:1px;">'+n+'</span> '}));
String.prototype.repeat = function( num ) {
return new Array( num + 1 ).join( this );
};
function toRoman(n) {
if(!n) return "";
var strn = new String(n);
var strnlength = strn.length;
var ret = "";
for(var i = 0 ; i < strnlength; i++) {
var index = strnlength*2 -2 - i*2;
var str;
var m = +strn[i];
if(index > rnumbers.length -1) {
str = rnumbers[rnumbers.length-1].repeat(m*Math.pow(10,Math.ceil((index-rnumbers.length)/2)));
}else {
str = rnumbers[index].repeat(m);
if (rnumbers.length >= index + 2) {
var rnregexp = rnumbers[index]
.split("(").join('\\(')
.split(")").join('\\)');
str = str.replace(new RegExp('(' + rnregexp + '){9}'), rnumbers[index] + rnumbers[index + 2])
.replace(new RegExp('(' + rnregexp + '){5}'), rnumbers[index + 1])
.replace(new RegExp('(' + rnregexp + '){4}'), rnumbers[index] + rnumbers[index + 1])
}
}
ret +=str;
}
return ret;
}
<input type="text" value="" onkeyup="document.getElementById('result').innerHTML = toRoman(this.value)"/>
<br/><br/>
<div id="result"></div>
Это первый раз, когда я действительно застрял на freecodecamp. Я просмотрел некоторые решения здесь и был поражен тем, насколько они были разными. Вот что для меня работало.
function convertToRoman(num) {
var roman = "";
var lookupObj = {
1000:"M",
900:"CM",
500:"D",
400:"CD",
100:"C",
90:"XC",
50:"L",
40:"XL",
10:"X",
9:"IX",
4:"IV",
5:"V",
1:"I",
};
var arrayLen = Object.keys(lookupObj).length;
while(num>0){
for (i=arrayLen-1 ; i>=0 ; i--){
if(num >= Object.keys(lookupObj)[i]){
roman = roman + lookupObj[Object.keys(lookupObj)[i]];
num = num - Object.keys(lookupObj)[i];
break;
}
}
}
return roman;
}
convertToRoman(1231);
Эти функции преобразуют любое положительное целое число в его эквивалентную строку Roman Numeral; и любую римскую цифру к ее числу.
Номер в римскую цифру:
Number.prototype.toRoman= function () {
var num = Math.floor(this),
val, s= '', i= 0,
v = [1000, 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'];
function toBigRoman(n) {
var ret = '', n1 = '', rem = n;
while (rem > 1000) {
var prefix = '', suffix = '', n = rem, s = '' + rem, magnitude = 1;
while (n > 1000) {
n /= 1000;
magnitude *= 1000;
prefix += '(';
suffix += ')';
}
n1 = Math.floor(n);
rem = s - (n1 * magnitude);
ret += prefix + n1.toRoman() + suffix;
}
return ret + rem.toRoman();
}
if (this - num || num < 1) num = 0;
if (num > 3999) return toBigRoman(num);
while (num) {
val = v[i];
while (num >= val) {
num -= val;
s += r[i];
}
++i;
}
return s;
};
Строка римской цифры в номер:
Number.fromRoman = function (roman, accept) {
var s = roman.toUpperCase().replace(/ +/g, ''),
L = s.length, sum = 0, i = 0, next, val,
R = { M: 1000, D: 500, C: 100, L: 50, X: 10, V: 5, I: 1 };
function fromBigRoman(rn) {
var n = 0, x, n1, S, rx =/(\(*)([MDCLXVI]+)/g;
while ((S = rx.exec(rn)) != null) {
x = S[1].length;
n1 = Number.fromRoman(S[2])
if (isNaN(n1)) return NaN;
if (x) n1 *= Math.pow(1000, x);
n += n1;
}
return n;
}
if (/^[MDCLXVI)(]+$/.test(s)) {
if (s.indexOf('(') == 0) return fromBigRoman(s);
while (i < L) {
val = R[s.charAt(i++)];
next = R[s.charAt(i)] || 0;
if (next - val > 0) val *= -1;
sum += val;
}
if (accept || sum.toRoman() === s) return sum;
}
return NaN;
};
Я разработал рекурсивное решение ниже. Функция возвращает одну букву, а затем вызывает себя, чтобы вернуть следующую букву. Он делает это до тех пор, пока число, переданное функции, не будет 0
, что означает, что все буквы найдены, и мы можем выйти из рекурсии.
var romanMatrix = [
[1000, 'M'],
[900, 'CM'],
[500, 'D'],
[400, 'CD'],
[100, 'C'],
[90, 'XC'],
[50, 'L'],
[40, 'XL'],
[10, 'X'],
[9, 'IX'],
[5, 'V'],
[4, 'IV'],
[1, 'I']
];
function convertToRoman(num) {
if (num === 0) {
return '';
}
for (var i = 0; i < romanMatrix.length; i++) {
if (num >= romanMatrix[i][0]) {
return romanMatrix[i][1] + convertToRoman(num - romanMatrix[i][0]);
}
}
}
В этом блоге есть приятная информация, которую я нашел с помощью google:
http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter
function romanize (num) {
if (!+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
или бросить вместо возврата false
, как обсуждалось в этом сообщении.
– Onur Yıldırım
12 October 2015 в 14:59
Эта функция преобразует любое число, меньшее чем 3999999, в римский. Обратите внимание, что числа, превышающие 3999, будут внутри метки с text-decoration
, установленными на overline
, это добавит overline
, которое является правильным представлением для x1000, когда число больше 3999.
Четыре миллиона (4 000 000) будут IV с двумя overline
s, поэтому вам нужно будет использовать какой-то трюк, чтобы представить это, возможно, DIV
с border-top
, или некоторое фоновое изображение с этими двумя overline
s .. Каждый overline
представляет x1000.
function convert(num){
num = parseInt(num);
if (num > 3999999) { alert('Number is too big!'); return false; }
if (num < 1) { alert('Number is too small!'); return false; }
var result = '',
ref = ['M','CM','D','CD','C','XC','L','XL','X','IX','V','IV','I'],
xis = [1000,900,500,400,100,90,50,40,10,9,5,4,1];
if (num <= 3999999 && num >= 4000) {
num += ''; // need to convert to string for .substring()
result = '<label style="text-decoration: overline;">'+convert(num.substring(0,num.length-3))+'</label>';
num = num.substring(num.length-3);
}
for (x = 0; x < ref.length; x++){
while(num >= xis[x]){
result += ref[x];
num -= xis[x];
}
}
return result;
}
JavaScript
function romanize (num) {
if (!+num)
return false;
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;
}
много других предложений можно найти в http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter
Я знаю, что это датированный вопрос, но у меня есть кратчайшее решение тех, которые перечислены здесь, и я думаю, что я поделюсь с тех пор, как я думаю, его легче понять.
Эта версия не требует жесткой кодированной логики для краевых случаев, таких как 4 (IV), 9 (IX), 40 (XL), 900 (CM) и т. д., как это делают другие. Это также означает, что он может обрабатывать большие числа, превышающие 3999, в теории, если применяется правило «не более 3 в строке».
Я тестировал это против 1-3999, и он работает безупречно.
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);
function convertToRoman(num) {
var roNumerals = {
M: Math.floor(num / 1000),
CM: Math.floor(num % 1000 / 900),
D: Math.floor(num % 1000 % 900 / 500),
CD: Math.floor(num % 1000 % 900 % 500 / 400),
C: Math.floor(num % 1000 % 900 % 500 % 400 / 100),
XC: Math.floor(num % 1000 % 900 % 500 % 400 % 100 / 90),
L: Math.floor(num % 1000 % 900 % 500 % 400 % 100 % 90 / 50),
XL: Math.floor(num % 1000 % 900 % 500 % 400 % 100 % 90 % 50 / 40),
X: Math.floor(num % 1000 % 900 % 500 % 400 % 100 % 90 % 50 % 40 / 10),
IX: Math.floor(num % 1000 % 900 % 500 % 400 % 100 % 90 % 50 % 40 % 10 / 9),
V: Math.floor(num % 1000 % 900 % 500 % 400 % 100 % 90 % 50 % 40 % 10 % 9 / 5),
IV: Math.floor(num % 1000 % 900 % 500 % 400 % 100 % 90 % 50 % 40 % 10 % 9 % 5 / 4),
I: Math.floor(num % 1000 % 900 % 500 % 400 % 100 % 90 % 50 % 40 % 10 % 9 % 5 % 4 / 1)
};
var roNuStr = "";
for (var prop in roNumerals) {
for (i = 0; i < roNumerals[prop]; i++) {
roNuStr += prop;
}
}
return roNuStr;
}
convertToRoman(9);
function convertToRoman(num) {
var romans = {
1000: 'M',
900: 'CM',
500: 'D',
400: 'CD',
100: 'C',
90: 'XC',
50: 'L',
40: 'XL',
10: 'X',
9: 'IX',
5: 'V',
4: 'IV',
1: 'I'
};
var popped, rem, roman = '',
keys = Object.keys(romans);
while (num > 0) {
popped = keys.pop();
m = Math.floor(num / popped);
num = num % popped;
console.log('popped:', popped, ' m:', m, ' num:', num, ' roman:', roman);
while (m-- > 0) {
roman += romans[popped];
}
while (num / popped === 0) {
popped = keys.pop();
delete romans[popped];
}
}
return roman;
}
var result = convertToRoman(3999);
console.log(result);
document.getElementById('roman').innerHTML = 'Roman: ' + result;
p {
color: darkblue;
}
<p>Decimal: 3999</p>
<p id="roman">Roman:</p>
function toRoman(n) {
var decimals = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
var roman = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'];
for (var i = 0; i < decimals.length; i++) {
if(n < 1)
return "";
if(n >= decimals[i]) {
return roman[i] + toRoman(n - decimals[i]);
}
}
}
Если он предназначен только для показа, используйте стандартный HTML с небольшим количеством JS для значения (если необходимо) и CSS, чтобы сделать его inline:
ol.roman-lowercase,
ol.roman-uppercase {
display: inline-flex;
margin: 0;
padding: 0;
}
ol.roman-lowercase {
list-style: lower-roman inside;
}
ol.roman-uppercase {
list-style: upper-roman inside;
}
<ol class="roman-lowercase"><li value="4"></li></ol> <!-- iv. -->
<ol class="roman-uppercase"><li value="142"></li></ol> <!-- CXLII. -->
/*my beginner-nooby solution for numbers 1-999 :)*/
function convert(num) {
var RomNumDig = [['','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']];
var lastDig = num%10;
var ourNumb1 = RomNumDig[0][lastDig]||'';
if(num>=10) {
var decNum = (num - lastDig)/10;
if(decNum>9)decNum%=10;
var ourNumb2 = RomNumDig[1][decNum-1]||'';}
if(num>=100) {
var hundNum = ((num-num%100)/100);
var ourNumb3 = RomNumDig[2][hundNum-1]||'';}
return ourNumb3+ourNumb2+ourNumb1;
}
console.log(convert(950));//CML
/*2nd my beginner-nooby solution for numbers 1-10, but it can be easy transformed for larger numbers :)*/
function convert(num) {
var ourNumb = '';
var romNumDig = ['I','IV','V','IX','X'];
var decNum = [1,4,5,9,10];
for (var i=decNum.length-1; i>0; i--) {
while(num>=decNum[i]) {
ourNumb += romNumDig[i];
num -= decNum[i];
}
}
return ourNumb;
}
console.log(convert(9));//IX
Эта функция работает с разными наборами символов в каждой цифре. Чтобы добавить еще одну цифру, добавьте римскую цифровую строку: 1 место, 5 место и следующее 1 место. Это хорошо, потому что вы обновляете его, зная только следующий набор символов.
function toRoman(n){
var d=0,o="",v,k="IVXLCDM".split("");
while(n!=0){
v=n%10,x=k[d],y=k[d+1],z=k[d+2];
o=["",x,x+x,x+x+x,x+y,y,y+x,y+x+x,y+x+x+x,x+z][v]+o;
n=(n-v)/10,d+=2;
}
return o
}
var out = "";
for (var i = 0; i < 100; i++) {
out += toRoman(i) + "\n";
}
document.getElementById("output").innerHTML = out;
<pre id="output"></pre>
function convertToRoman(num) {
var romNumerals = [["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 runningTotal = 0;
var roman = "";
for (var i = 0; i < romNumerals.length; i++) {
while (runningTotal + romNumerals[i][1] <= num) {
runningTotal += romNumerals[i][1];
roman += romNumerals[i][0];
}
}
return roman;
}
Все еще горжусь этим :) Он работает между 1-3999.
var converterArray = [{"1":["I","IV","V","IX"],
"2":["X","XL","L","XC"],
"3":["C","CD","D","CM"],
"4":["M"]}
];
function convertToRoman(num) {
var romanNumeral = [];
var numArr = num.toString().split('');
var numLength = numArr.length;
for (var i = 0; i<numArr.length; i++) {
if (numArr[i] < 4) {
for (var j = 0; j<numArr[i]; j++) {
romanNumeral.push(converterArray[0][numLength][0]);
}
} else if (numArr[i] < 5) {
for (var j = 3; j<numArr[i]; j++) {
romanNumeral.push(converterArray[0][numLength][1]);
}
} else if (numArr[i] < 9) {
romanNumeral.push(converterArray[0][numLength][2]);
for (var j = 5; j<numArr[i]; j++) {
romanNumeral.push(converterArray[0][numLength][0]);
}
} else if (numArr[i] < 10) {
for (var j = 8; j<numArr[i]; j++) {
romanNumeral.push(converterArray[0][numLength][3]);
}
}
numLength--;
}
return romanNumeral.join('');
}
convertToRoman(9);
function romanize(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] ) {
roman += i;
num -= lookup[i];
}
}
return roman;
}
Отправлено из комментария 2008 года, расположенного по адресу: http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter
for...in
.
– Oriol
31 July 2016 в 22:01