简体   繁体   English

Javascript for loop 在计算 LCM 时给出无限循环错误

[英]Javascript for loop giving infinite loop error while calculating LCM

The problem I'm trying to solve is to calculate least common multiple of a given range of numbers.我要解决的问题是计算给定数字范围的最小公倍数。 The numbers supplied in the array can be in any order, but the attay will only have two numbers.数组中提供的数字可以按任意顺序排列,但 attay 只有两个数字。

My code works for pairs [1,5], [1,10],[1,12], but once I try [1,13] i'm getting infinite loop error and answer is becoming undefined.我的代码适用于对 [1,5]、[1,10]、[1,12],但是一旦我尝试 [1,13],我就会遇到无限循环错误并且答案变得不确定。

For below code, expected answer is 360360对于以下代码,预期答案是 360360

function smallestCommons(arr) {

  var a     = arr[0];
  var b     = arr[1];
  var start = 0;
  var end   = 0;
 
  if (a<b) {
    start=a;
    end=b;
  }
  else {
    start=b;
    end=a;
  }

  //console.log("Start:"+start);
  //console.log("End:"+end);

  var numArray = [];
  for(let i=start; i<end+1; i++) {
    numArray.push(i);
  }

  console.log(numArray);
  
  var oddArray = [];
  var product  = numArray.reduce((a,b)=>a=a*b);
  
  console.log("Product:"+product);
  console.log(numArray[0]);
  
  var result = 0;
  
  console.log(result);

  //let j=numArray[0];

  for(let j=numArray[0];j<=product;j++) {
    var count = 0;
    for(let k=0;k<numArray.length; k++) {
  
      if(j%numArray[k]==0) {
        count++;
      }
    }
    if(count==numArray.length) {
      return j;
    }
  }
}

console.log(smallestCommons([1,13]));

it should be product.length-1 as reduce returns an array它应该是 product.length-1 因为 reduce 返回一个数组

for(let j=numArray[0];j<=product.length-1;j++) {

Your approach is wrong.你的方法是错误的。

What is the LCM of 1, 2, 3, 4? 1、2、3、4的LCM是多少? It is 12 because it is 3 x 4.它是 12,因为它是 3 x 4。

What your code will do:您的代码将做什么:

var product  = numArray.reduce((a,b)=>a=a*b); // product will be 24
...
for(let j=numArray[0];j<=product;j++) { // iterate from 1 -> 24
    var count = 0;
    for(let k=0;k<numArray.length; k++) { // iterate from 0 -> 3
  
      if(j%numArray[k]==0) { // consider it a hit if j is divisible by an element
        count++;
      }
    }
    if(count==numArray.length) { // on the 4th "hit"
      return j; // return j which is a number between 1 -> 24
    }
  }

If you are running into an infinite loop, it's because you don't get the right number of hits.如果您遇到无限循环,那是因为您没有获得正确的点击次数。

The correct approach to an LCM question is to think about prime factors. LCM 问题的正确方法是考虑主要因素。 Let's use 1, 2, 3, 4 again.让我们再次使用 1、2、3、4。

For each number, I get a count of prime factors.对于每个数字,我都会计算素数。

1 -> 1(1)
2 -> 2(1), 1(1)
3 -> 3(1), 1(1)
4 -> 2(2), 1(1)

We reduce this set by using max(cnt) for each prime factor.我们通过对每个素因子使用 max(cnt) 来减少这个集合。 The max count of 1 is 1. The max count of 2 is 2. The max count of 3 is 1. So we then go: 2 x 2 x 3 = 12, and that is our answer. 1 的最大计数是 1。2 的最大计数是 2。3 的最大计数是 1。所以我们然后 go:2 x 2 x 3 = 12,这就是我们的答案。

This requires 2 passes:这需要 2 次通过:

  1. first pass over the numbers array.首先通过 numbers 数组。
  2. second pass over the prime count map.第二次通过素数 map。

...my way: ...我的方式:

 function isPrime(n) { if(n < 2) return false for (let x = 2; x < n; ++x) if (n%x===0) return false return true } function smallestCommons(range) { let nMin = Math.min(...range), nTab = [], xPow = {}; for (let n = Math.max(...range); n >1; --n) { if (n>=nMin &&.(nTab.find(x=>(x%n===0))) ) nTab.push(n) if (isPrime(n)) { nTab.forEach(v=> { if(v%n===0) { let p = 0 while ((v%(n**++p))===0) {} --p if (,xPow[n] ) xPow[n] = p else xPow[n] = Math.max(xPow[n]. p) } }) } } return Object,entries(xPow),reduce((a,[vp])=>a*(v**p),1) } console,log ('[1,4] ->'. smallestCommons([1,4]) ) console,log ('[1,5] ->'. smallestCommons([1,5]) ) console,log ('[1,10] ->'. smallestCommons([1,10]) ) console,log ('[1,12] ->'. smallestCommons([1,12]) ) console,log ('[1,13] ->', smallestCommons([1,13]) )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM