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;
};
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;
}
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;
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;
}
function converter(numToConv) {
var numToRom = []; //an array empty, ready to store information about the numbers we will use as we analyse the given number
var numToRome = ""; // this is a string to add the Roman letters forming our returning number
var R = [['M',1000], ['D',500], ['C',100], ['L',50], ['X',10], ['V',5], ['I',1]]; //this array stores the matches with the arabic numbers that we are going to need
while (numToConv > 0) { //just checking, there is no zero
if (numToConv > R[0][1]) { //checks if the number is bigger than the bigger number in the array
if (numToConv < R[0][1] * 5 - R[0][1]) { //checks if it is larger even than 4 times the larger number in the array (just because there is not usually a way to express a number by putting 4 times the same letter i.e there is no "IIII", or "XXXX" etc)
numToRom.push([R[0][0],"next one goes aftah"]);//here is the information we want to pass, we add the letter we are about to use along with info about the next letter
numToConv = Math.abs(numToConv - R[0][1]);// and now we are subtracting the value of the letter we are using from the number
console.log("Next comes after: " + R[0][0] + " (" + R[0][1] + ")");// informing about what we encountering
console.log(numToConv);//..as well as what's the next number
} else { //if the number is larger than 4 times the larger number in the array (thus it cannot be expressed)
numToConv = 0; //then 0 the number (unnecessary but still, no problem doing it)
break;//and of course, breaking the loop, no need to continue
}
}
for (var i = 0; i < R.length; i++) {//now we are about to search our number for each cell of the array with the roman letters (again and again)
if (R[i][1] == numToConv) { //if the number is equal to the one in the cell (that means the conversion is over)
numToRom.push([R[i][0],"end"]); //we pass the information about that cell along with the indication that the conversion has ended
numToConv = Math.abs(numToConv - R[i][1]);//thai can also be skipped but again there is o harm in keeping it
console.log("End: " + numToConv);// again informing about what we encountering
} else if (i > 0) { //just a precaution because we are about to use "i-1"
if ((R[i-1][1] > numToConv) && (R[i][1] < numToConv)) {//we find the range in which is the given number (for instance: the number 4 is between 1[I] and 5[V])
console.log(numToConv + " is between: " + R[i][1] + " (" + R[i][0] + ") and: " + R[i - 1][1] + " (" + R[i - 1][0] + ")");// once again informing
var threshold = R[i - 1][1] - Math.pow(10, numToConv.toString().length - 1);// we create this "threshold" to check if the next number is going before or after this one (difference between 7[VII] and 9[IX]). it is the larger number of our range - 10^[depends on how large is the number we want to convert] (for 999, the threshold is 900, it is smaller 1000 - 10^2)
console.log("threshold: " + threshold + " : " + numToConv + " : " + R[i - 1][1] + " : " + R[i][1] + " : " + Math.pow(10, numToConv.toString().length - 1));
if (numToConv < threshold) {//if the number is smaller than the "threshold" (like 199 where its threshold is 400)
numToRom.push([R[i][0],"next one goes aftah"]);//then the next number is going after
numToConv = Math.abs(numToConv - R[i][1]);//and again, subtract the used value of the number we are converting
console.log("Next comes after: " + R[i][0] + " (" + R[i][1] + ")");
console.log(numToConv);
} else { // now, if the number is larger than the threshold (like 99 where its threshold is 90)
numToRom.push([R[i-1][0],"next one goes befoah"]);// then the next number is going before the one we add now
numToConv = Math.abs(numToConv - R[i - 1][1]);// again, the subtraction, it was "threshold + Math.pow(10, numToConv.toString().length - 1)" but I changed it to "R[i - 1][1]", same result, less operations
console.log("Next comes before: " + R[i-1][0] + " (" + R[i-1][1] + ")");
console.log(numToConv);
}
}
}
}
}
console.log("numToRom: " + numToRom); //now that we have all the info we need about the number, show it to the log (just for a check)
for (var i = 0; i < numToRom.length; i++) {//..and we start running through that info to create our final number
if (numToRom[i][1] == "next one goes befoah") {//if our information about the cell tells us that the next letter is going before the current one
numToRome += (numToRom[i+1][0] + numToRom[i][0]);// we add both to our string (the next one first)
console.log("numToRome goes befoah: " + numToRome + " i: " + i);
i++;//and we add an extra '1' to the i, so it will skip the next letter (mind that there won't be more than one letters saying that the next one is going before them in a row
} else {//if the next one is going after the current one
numToRome += numToRom[i][0]; //we just add the one we are on to the string and go forth
console.log("numToRome goes aftah: " + numToRome + " i: " + i);
}
}
console.log("numToRome: " + numToRome);
return numToRome;//return the string and we are done
}
似乎有一个交替的规则来决定下一个主要的罗马数字字符。首先乘以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);
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;
}
function convertToRoman(num) {
var uni = ["","I","II","III","IV","V","VI","VII","VIII","IX"];
var dec = ["","X","XX","XXX","XL","L","LX","LXX","LXXX","XC"];
var cen = ["","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"];
var mil = ["","M","MM","MMM","MMMM","MMMMM","MMMMMM","MMMMMMM","MMMMMMMM","MMMMMMMMMM"];
var res =[];
if(num/1000 > 0)
{
res = res.concat(mil[Math.floor(num/1000)]);
}
if(num/100 > 0)
{
res = res.concat(cen[Math.floor((num%1000)/100)]);
}
if(num/10 >0)
{
res = res.concat(dec[Math.floor(((num%1000)%100)/10)]);
}
res=res.concat(uni[Math.floor(((num%1000)%100)%10)]);
return res.join('');
}
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;
}
//a function that convert a single number to roman number, you can choose how to convert it so later you can apply to different part of the number
function romannum(num,rnum1,rnum2,rnum3){
var result = "";
if(num >= 1 && num < 4){
while(num>0){
result += rnum1;
num--;
}
}
else if(num > 5 && num < 9){
result = rnum2;
while(num>5){
result += rnum1;
num--;
}
}
else if(num == 4){
result += rnum1 + rnum2;
}
else if( num == 5){
result += rnum2;
}
else if( num == 9){
result += rnum1+ rnum3;
}
return result;
}
//the main function
function convertToRoman(num) {
num = num.toString().split('');
var length = num.length;
var x = 0;
var result =[];
while((length - x) > 0){
if(length -x === 4){
result.push(romannum(num[x],"M","",""));
}
else if(length -x === 3){
result.push(romannum(num[x],"C","D","M"));
}
else if(length - x === 2){
result.push(romannum(num[x],"X","L","C"));
}
else if(length - x === 1){
result.push(romannum(num[x],"I","V","X"));
}
x++;
}
letterTable = {
0:{
1:'I',
5:'V',
10:'X'
},
1:{
1:'X',
5:'L',
10:'C'
},
2:{
1:'C',
5:'D',
10:'M'
},
3:{
1:'M',
5:'V', // There should be a dash over this letter
10:'X' // There should be a dash over this letter
},
// you can add new level of letters here
};
function romanLetter(i, j){
romanTable = {
'0':'',
'1':letterTable[i][1],
'2':letterTable[i][1]+letterTable[i][1],
'3':letterTable[i][1]+letterTable[i][1]+letterTable[i][1],
'4':letterTable[i][1]+letterTable[i][5],
'5':letterTable[i][5],
'6':letterTable[i][5]+letterTable[i][1],
'7':letterTable[i][5]+letterTable[i][1]+letterTable[i][1],
'8':letterTable[i][5]+letterTable[i][1]+letterTable[i][1]+letterTable[i][1],
'9':letterTable[i][1]+letterTable[i][10]
};
return romanTable[j];
}
function convertToRoman(num) {
numStr = String(num);
var result = '';
var level = 0;
for (var i=numStr.length-1; i>-1; i--){
result = romanLetter(level, numStr[i]) + result;
level++;
}
return result;
}
function convertToRoman(num) {
var value = [];
var temp, base, buffer;
var letters = ['I', 'V', 'X', 'L', 'C', 'D', 'M'];
var offsets = [
[1, 0], // 1
[2, 0], // 2
[3, 0], // 3
[-1, 1], // 4
[0, 1], // 5
[1, 1], // 6
[2, 1], // 7
[3, 1], // 8
[-2, 2], // 9
];
// cascade through each denomination (1000's, 100's, 10's, 1's) so that each denomination is triggered
// Thousands
if (num >= 1000) {
temp = Math.floor(num / 1000);
buffer = offsets[temp - 1];
base = 6;
value.push(getValue(base, letters, buffer));
num -= temp * 1000;
}
// Hundreds
if (num >= 100) {
temp = Math.floor(num / 100);
buffer = offsets[temp - 1];
base = 4;
value.push(getValue(base, letters, buffer));
num -= temp * 100;
}
// Tens
if (num >= 10) {
temp = Math.floor(num / 10);
buffer = offsets[temp - 1];
base = 2;
value.push(getValue(base, letters, buffer));
num -= temp * 10;
}
// Ones
if (num > 0) {
buffer = offsets[num - 1];
base = 0;
value.push(getValue(base, letters, buffer));
}
// Finish
return value.join('');
}
function getValue(base, letters, buffer) {
var val1 = buffer[0], val2 = buffer[1];
var value = [];
// If val1 is less than 0 then we know it is either a 4 or 9, which has special cases
if (val1 < 0) {
// Push the base index, then push the base plus the val2 offset
value.push(letters[base]);
value.push(letters[base + val2]);
} else {
// Push a letter if val2 is set - meaning we need to offset a number that is equal to or higher than 5
// 5 is basically the only scenario which this will exist
if (val2 > 0) value.push(letters[base + val2]);
// Now add in the next letters of the base for the inciment
for (var i = 0; i < val1; i++) {
value.push(letters[base]);
}
}
return value.join('');
}
convertToRoman(90);
我很确定伴随函数意味着它可以有几乎无限的潜力假设你提供了正确的符号来表示大于 M 的数但是不要引用我的话。
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;
}
只是想知道 Piotr Berebecki 的答案。
我对它进行了编辑,这样递归函数不仅可以从给定的数字中减去1,还可以立即减去所提供数组中最高匹配的数字,以加快处理速度。
// the arrays
var arabicFormat = [1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000];
var romanFormat = ['I', 'IV', 'V', 'IX', 'X', 'XL', 'L', 'XC', 'C', 'CD', 'D', 'CM', 'M'];
function convertToRoman(num) {
// the recursion will stop here returning a blank
if (num === 0){
return '';
}
var returnValue = [];
// this is the main For loop of the function
for (var i=0; i < arabicFormat.length; i++){
if (num >= arabicFormat[i]){
// empty the array on every iteration until it gets to the final number
returnValue = [];
// store the current highest matched number in the array
returnValue.push(romanFormat[i]);
}
}
// get the correct resulting format
returnValue = returnValue.join();
// get the highest matched number value
var whatIndex = romanFormat.indexOf(returnValue);
var substractValue = arabicFormat[whatIndex];
// here the recursion happens
return returnValue + convertToRoman(num - substractValue);
}
var intToRoman = function(num) {
let symbolMap = ['I','V','X','L','C','D','M','P','Q'];
if (num < 1 || num > 9999) {
return null;
}
let i = 0;
let result = '';
while (num) {
let digit = num % 10;
num = parseInt(num / 10);
switch (digit) {
case 1: result = symbolMap[i] + result;
break;
case 2: result = symbolMap[i] + symbolMap[i] + result;
break;
case 3: result = symbolMap[i] + symbolMap[i] + symbolMap[i] + result;
break;
case 4: result = symbolMap[i] + symbolMap[i+1] + result;
break;
case 5: result = symbolMap[i+1] + result;
break;
case 6: result = symbolMap[i+1] + symbolMap[i] + result;
break;
case 7: result = symbolMap[i+1] + symbolMap[i] + symbolMap[i] + result;
break;
case 8: result = symbolMap[i+1] + symbolMap[i] + symbolMap[i] + symbolMap[i] + result;
break;
case 9: result = symbolMap[i] + symbolMap[i+2] + result;
break;
}
i += 2;
}
return result;
};
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));
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;
}
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;
};
I'm beginner, and I see like that ))) without arrays . of course it would be better with itter + acc in function..
刚刚通过了 freeCodeCamp 的测试
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
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;
}
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
const arabic_benchmarks = Object.keys(roman_benchmarks);
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 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 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
}
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,那么你就不需要上面对象中有两个 roman 字符的属性了。
然后构建一个函数来完成从基数到罗马数字的神奇转换:
// 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;
};
最后,如果你想做逆运算,那么构建一个函数来将 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;
}
didn't see a matrix array being used together with a for and a nested ternary operator, looks fancy but it's barely out of the hard-code zone, hope you like it!.
function rome(num) {
if (num > 3999) {return 'number too large'};
let strNum = JSON.stringify(num).split("");
let number = [];
let romans = [ ['I','IV','V','IX'],
['X','XL','L','XC'],
['C','CD','D','CM'],
['M','','',''] ];
for (let j = strNum.length - 1 ; 0 <= j; j--){
let digit ='';
digit = strNum[j] == 0 ? '' :
strNum[j] <= 3 ?
romans[strNum.length-1-j][0].repeat(Number(strNum[j])) :
strNum[j] == 4 ? romans[strNum.length-1-j][1] :
strNum[j] == 5 ? romans[strNum.length-1-j][2] :
strNum[j] <= 8 ? romans[strNum.length-1-j][2] +
romans[strNum.length-1-j][0].repeat(Number(strNum[j])-5) :
romans[strNum.length-1-j][3] ;
number.unshift(digit);
};
return ''.concat(number.join(''));
}
class RomanNumeral {
constructor(value, symbol){
this.value = value;
this.symbol = symbol;
}
}
const romanNumerals = [
new RomanNumeral(1000, "M"),
new RomanNumeral(900, "CM"),
new RomanNumeral(500, "D"),
new RomanNumeral(400, "CD"),
new RomanNumeral(100, "C"),
new RomanNumeral(90, "XC"),
new RomanNumeral(50, "L"),
new RomanNumeral(40, "XL"),
new RomanNumeral(10, "X"),
new RomanNumeral(9, "IX"),
new RomanNumeral(5, "V"),
new RomanNumeral(4, "IV"),
new RomanNumeral(1, "I"),
];
function roman(number) {
assertNumberInRomanLimits(number);
let result = "";
for (const { value , symbol } of romanNumerals){
while(number >= value){
result += symbol;
number -= value;
}
}
return result;
}
function assertNumberInRomanLimits(number) {
if (number > 3999) {
throw new RangeError("The biggest number we can form in Roman numerals is MMMCMXCIX (3999).");
}
if (number < 1) {
throw new RangeError("There is no concept of 0 or negatives in Roman numerals.");
}
};
console.log(roman(3)); //=> "III"
console.log(roman(47)); //=> "XLVII"
console.log(roman(3990)); //=> "MMMCMXC"
console.log(roman(3999)); //=> "MMMCMXCIX"
console.log(roman(1984)); //=> "MCMLXXXIV"
// For each power of 10, we break down the number
// and build up the roman numeral characters
function convertToRoman(num) {
let roman = [];
[roman, num] = convertPowerOfTen(roman, num, 1000, "M");
[roman, num] = convertPowerOfTen(roman, num, 100, "C", "D");
[roman, num] = convertPowerOfTen(roman, num, 10, "X", "L");
[roman, num] = convertPowerOfTen(roman, num, 1, "I", "V");
return roman.join("");
}
function convertPowerOfTen(roman, num, multiplier, unitChar, fiveChar) {
// Handle multiple of 5, possibly going into "debt"
if (num >= 4 * multiplier) {
roman.push(fiveChar);
num -= 5 * multiplier;
}
// If in debt, insert unit character before the last one
if (num <= -1) {
roman.splice(-1, 0, unitChar)
num += multiplier;
}
// Insert as many unit characters as needed
while (num >= multiplier * 0.9) {
roman.push(unitChar);
num -= multiplier;
}
return [roman, num];
}