Javascript 罗马数字转换器

Javascript 罗马数字转换器,javascript,Javascript,我无法正确理解此解决方案。我理解数组声明部分,但不确定while循环中发生了什么 function roman(num) { var decimalValue = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]; var romanNumeral = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I']; var romanized

我无法正确理解此解决方案。我理解数组声明部分,但不确定while循环中发生了什么

function roman(num) {
  var decimalValue = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
  var romanNumeral = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'];
  var romanized = '';

  for (var index = 0; index < decimalValue.length; index++) {
    while (decimalValue[index] <= num) {
      romanized += romanNumeral[index];
      num -= decimalValue[index];
    }
  }

  return romanized;
}
函数(num){
风险值小数=[100090050040010090504010,9,5,4,1];
变量RomanNumeric=['M'、'CM'、'D'、'CD'、'C'、'XC'、'L'、'XL'、'X'、'IX'、'V'、'IV'、'I'];
var罗马化=“”;
对于(var索引=0;索引<小数点值.length;索引++){

虽然(decimalValue[index]下次您遇到这样的基于循环的问题时,我建议您学习命令和


让我们以一个特定的数字为例,比如说……2652。下面是将会发生的情况:

  • 从1000开始(小数点后的第一个数字),检查2562是否大于1000
  • 是的!所以,我们知道2652的罗马数字中至少有一个M。我们把M加到输出的罗马数字中
  • 我们已经将数字中的1000作为一个数字进行了“计算”,所以我们从数字中删除了1000。现在我们有1562
  • 我们跳回到检查1000。它仍然是。所以,我们再加上一个M,再减去一个1000。现在我们有562个数字“未解释”
  • 这一次,当我们跳到
    while()
    循环的开始,测试if
    num
    >1000时,我们发现情况并非如此!因此这次循环没有运行
此过程对
小数中的所有数字重复;所有具有罗马数字等价物的数字重复

因此,我们检查900/CM,发现这个数字(现在降到562)不能表示为包含900的总和

接下来,我们检查500,发现它可以!我们将500的罗马数字添加到当前的
罗马化的
字符串中并继续。我们现在有
MMD
,我们的数字降到了62个“未计算”数字/单位/无论我们在计算什么

下一个捕捉
while()
循环的数字是50,因为62>50。我们将L添加到50,并将数字降到12。然后再次添加到10,并添加一个X。最后,我们匹配
小数点中的最后一项,1,两次,并添加两个
I
s


这个数字的最后一个字符串2652是。

While循环从索引0到最后一个进行比较,如果传入的num值小于十进制值数组的索引处的值,则进行比较。如果是,则它将追加(连接)该特定索引处的鲁曼数字用于随机化,并从发送的num中减去十进制的等效数字(对num变量进行变异)。 然后检查num是否仍然大于指示十进制的特定索引处的值。 以3002为例进行演练

  • 首先检查包含1000的索引0是否小于3002 true
  • 将randomize设置为位置索引处的ruman数字。在这种情况下,我们有'M',然后从num(3002)中减去位置索引处的十进制数,我们现在有num=2002
  • while循环再次迭代并检查是否比2002年少1000?是的,因此它将再次执行while循环的主体
  • 追加(将位置索引处的值(尚未更改)连接到随机化变量。这种情况下,索引仍然为零,因此我们追加的“M”现在随机化为“MM”。从num(2002)中减去位置索引处的小数(0),我们现在得到num=1002
  • 迭代while循环,并检查decimalValue数组的位置索引(0)处的十进制值是否小于num(1002),在本例中为true。如前所述执行循环。 追加(连接位置索引处的值(尚未更改)到随机化变量此案例索引仍然为零,因此我们现在追加“M”随机化为“MMM”。从num(1002)中减去位置索引处的小数(0),我们现在的num=2
  • 迭代while循环并检查decimalValue数组的位置索引(0)处的十进制值是否小于num(2),在这种情况下,num(2)为
    false
    。停止循环的执行并增加for循环中的索引值,然后再次进行检查。直到结束

  • 对于任何
    i
    ,小数值[i]表示与
    罗马数字[i]
    相同的值。这表示与作者使用对象
    {4:“IV”,5:“V”,…}相同的数据
    除了不保留顺序的对象。由于作者希望先检查较大的数字,再检查较小的数字,因此他们使用此选项来保留顺序,并将十进制值与罗马数字关联

    循环令人困惑,因为javascript使用
    +
    来表示数字相加、
    2+4==6
    ,以及字符串串联、
    “a”+“b”==ab”

    romanized+=romanNumeral[index]
    表示将
    romanNumeral[index]
    中包含的字符串附加到字符串的末尾
    romanized

    num-=decimalValue[index];
    表示将
    num
    减少
    decimalValue[index]

      //start at the big values that have roman number codes, then try smaller values
      for (var index = 0; index < decimalValue.length; index++) {
        //if the value we are testing is less or equal to num 
        // (actually loop but for reasons explained below)
        while (decimalValue[index] <= num) {
    
          //append the string in romanNumberal to 
          //the end of the string in the variable romanized
          romanized += romanNumeral[index];
    
          //from the number num, substract the
          //value we just added to romanized 
          num -= decimalValue[index];
    
          //what about a case like 3, which needs 
          //repeated letters in that case "III".
    
          //That is why this is a while statement and not an if. 
          //the while loop keeps processing 
          //those cases until we have enough repeated letters.
        }
      }
    
    //从包含罗马数字代码的大值开始,然后尝试较小的值
    对于(var索引=0;索引<小数点值.length;索引++){
    //如果我们正在测试的值小于或等于num
    //(实际上是循环,但原因如下)
    while(decimalValue[index]=2
    (即
    decimalValue[i]
    中的一个值中有2个或多个与前一个decimalValue匹配)

    如果你从数学中知道除法算法,这有点像