1

我在这里找到了功能。它接受一个整数数组并返回它们的最大公约数。有时它会陷入无限循环并使浏览器崩溃。我想调试它以找到原因,但我不明白fors 中使用的语法。如何将这些重写为普通for(var i; i<max; i++)循环?

mdc = function(o){
    if(!o.length)
        return 0;
    for(var r, a, i = o.length - 1, b = o[i]; i;)
        for(a = o[--i]; r = a % b; a = b, b = r);
    return b;
}; 
4

5 回答 5

2

这是从 for 循环到 while 循环的字面翻译:

mdc = function(o){
    if(!o.length)
        return 0;
    var r;
    var a;
    var i = o.length - 1;
    var b = o[i];
    while (i) {
        a = o[--i];            
        while (r = a % b) {
            a = b;
            b = r;
        }
    }        
    return b;
}; 

这是一个解开一些愚蠢并重命名变量的翻译:

mdc = function(o){
    if(!o.length)
        return 0;
    var cur_index = o.length - 1;
    var b = o[cur_index];
    while (cur_index) {
        cur_index -= 1;
        var a = o[cur_index];              

        var remainder = a % b;         
        while (remainder) {
            a = b;
            b = remainder;
            remainder = a % b;
        }
    }        
    return b;
}; 
于 2012-08-24T02:28:13.070 回答
1

我试试看

var r, a, i = o.length - 1
var b = o[i];

while(i) {
  a = o[--i];
  while(r = a % b) {
   a = b;
   b = r;
 }
 return b;
}
于 2012-08-24T02:25:08.957 回答
1

这与您过去看到的相同,但每个部分都有更多步骤。分为三个部分:

第 1 部分:它初始化变量;

第 2 部分:它验证 for 是否应该继续迭代

第 3 部分:增加或减少变量;

如果你看它,你会看到一些逗号;它用于声明多个变量或条件。下面的代码与您发布的代码相同,但您看起来很熟悉:

mdc = function(o){
if(!o.length)
    return 0;
    var r;
    var a;
    var i = o.length - 1;
    for(var b = o[i]; i;) {
        for(a = o[--i]; r = a % b;b = r) {
           a = b;
        }
        return b;
    }
}; 

您会注意到第二个 for 以“;”结尾,相当于命令行,这就是为什么其中只有“a = b”命令,而不是“return b”;

于 2012-08-24T02:26:33.793 回答
1

那么 for 循环的基本公式是

for(initial code; condition to check for; code to execute after loop)
{
    loop
}

我不喜欢该代码中的语法。只需在顶部声明所有变量。由于您的最大兴趣是调试代码,因此最好每行有一个语句。

mdc = function(o)
{
    if(!o.length)
        return 0;
    var r, a, b, i;
    i = o.length - 1;
    b = o[i];
    while(i)
    {
        a = o[i];
        i--;
        while(r = a % b)
        {
            a = b;
            b = r;
        }
    }
    return b;
};
于 2012-08-24T02:30:18.647 回答
1

``我认为问题在于 (a,b) 需要根据哪个更大来互换。(第二个 for 循环)。欧几里得算法就是这样做的。这个似乎没有这样做。

数字数组的 GCD:我会使用标准的欧几里得算法。

如果您从末尾迭代: GCD (a,b) =K
现在调用 GCD(K,next_element_in_array) 。那应该行得通。

enter code here
  Written in Pseudo-code What he is trying to do is more understandable:  
   For(b =array[end];   )    
     { 
      For(a= array[end-1]; end >=0 ;end --)  
          {
          (i)Divide a/b
          (ii)Put the new 'reduced' divisor in 'b'.
         (iii)Put the reminder back in c 
          }     
         end --
      } 

           }
       }

因此,在循环结束时,他试图模拟的任何东西都是一系列数字的 gcd 的手除计算 - 高中技巧!

正如我上面提到的,问题在于交换更大的 (a,b)。

于 2012-08-24T02:31:42.790 回答