Я только что опубликовал функцию, которую я сделал, чтобы конвертировать в Роман, надеюсь, вам понравится
function converter(numToConv) {
var numToRom = [];
var numToRome = "";
var R = [['M',1000], ['D',500], ['C',100], ['L',50], ['X',10], ['V',5], ['I',1]];
while (numToConv > 0) {
if (numToConv > R[0][1]) {
if (numToConv < R[0][1] * 5 - R[0][1]) {
numToRom.push([R[0][0],"next one goes aftah"]);
numToConv = Math.abs(numToConv - R[0][1]);
console.log("Next comes after: " + R[0][0] + " (" + R[0][1] + ")");
console.log(numToConv);
} else {
numToConv = 0;
break;
}
}
for (var i = 0; i < R.length; i++) {
if (R[i][1] == numToConv) {
numToRom.push([R[i][0],"end"]);
numToConv = Math.abs(numToConv - R[i][1]);
console.log("End: " + numToConv);
} else if (i > 0) {
if ((R[i-1][1] > numToConv) && (R[i][1] < numToConv)) {
console.log(numToConv + " is between: " + R[i][1] + " (" + R[i][0] + ") and: " + R[i - 1][1] + " (" + R[i - 1][0] + ")");
var threshold = R[i - 1][1] - Math.pow(10, numToConv.toString().length - 1);
console.log("threshold: " + threshold + " : " + R[i][1] + " : " + Math.pow(10, numToConv.toString().length - 1));
if (numToConv < threshold) {
numToRom.push([R[i][0],"next one goes aftah"]);
numToConv = Math.abs(numToConv - R[i][1]);
console.log("Next comes after: " + R[i][0] + " (" + R[i][1] + ")");
console.log(numToConv);
} else {
numToRom.push([R[i-1][0],"next one goes befoah"]);
numToConv = Math.abs(numToConv - threshold + Math.pow(10, numToConv.toString().length - 1));
console.log("Next comes before: " + R[i-1][0] + " (" + R[i-1][1] + ")");
console.log(numToConv);
}
}
}
}
}
console.log("numToRom: " + numToRom);
for (var i = 0; i < numToRom.length; i++) {
if (numToRom[i][1] == "next one goes befoah") {
numToRome += (numToRom[i+1][0] + numToRom[i][0]);
console.log("numToRome goes befoah: " + numToRome + " i: " + i);
i++;
} else {
numToRome += numToRom[i][0];
console.log("numToRome goes aftah: " + numToRome + " i: " + i);
}
}
console.log("numToRome: " + numToRome);
return numToRome;
}
Отредактированный код с комментариями:
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
}