0

大家好,我正在尝试创建一个接收两个数字的 LCM 函数。这段代码中的 findCommonMultiple() 函数基本上返回一个数组,该数组包含该数字的主要因子。我在这个函数中试图做的是检查两个数组中是否有重复,如果有的话,这个数字将被推入一个新数组中。在推入一个数字后,内部循环应该中断并继续下一次迭代。如果两个数字不相等,它们都将被推送。即使其中一个数组超过了它们的索引,这种情况也会继续。在推送所有重复因子和唯一因子之后,我将开始将它们相乘并返回两个数字的 LCM。我还没有为此创建一个辅助函数,但我需要先解决这个问题。

  function leastCommonMultiple(num1, num2){
  var prime1 = findPrimeFactors(num1);
  var prime2 = findPrimeFactors(num2);
  var primes = []; 
  var lcm = 1;


  for(var i = 0; i < prime1.length; i++){
    var factor1 = prime1[i];
    for(var j = i; j < prime2.length; j++){
      var factor2 = prime2[j];
      if(factor1 === factor2){
        primes.push(factor1);
        break;
      } else if(factor1 === undefined && factor2 > 0){
        primes.push(factor2);
      } else if(factor2 === undefined && factor2 > 0){
        primes.push(factor1)
      } else {
        primes.push(factor1);
        primes.push(factor2);
        break;
      }
    }
  }
  return primes;
}

编辑:所以我要添加一个测试用例。因此,如果我传递了值 26 和 24,我将得到两个数组。一个是[2, 2, 2, 3],另一个是[2, 13]。此函数会将我的重复项放入新数组中,并添加所有其他不重复项,因此:[2]首先是因为两个数组都有 2,然后[2, 2, 2, 3, 13]将其余没有重复项的数字添加到数组中。

4

3 回答 3

0

如果您只需要两个数组中的唯一项目,我建议这样做,

首先将两个数组连接起来并存储在一个新数组中,在这种情况下,

var tempPrimes= prime1.concat(prime2);

然后只需编写一个简单的过滤器来过滤掉唯一值,

var primes = tempPrimes.filter(function(item, pos){
  return tempPrimes.indexOf(item)== pos; 
});

如果您还想删除 0 值,则只需稍微修改一下,

var primes = tempPrimes.filter(function(item, pos){
  return tempPrimes.indexOf(item)== pos && tempPrimes[pos]!=0; 
});

希望我有所帮助:)

编辑(在进一步澄清问题后):

var tempPrimes= prime2.filter(function(item) {
  return prime1.indexOf(item) < 0;
});


var primes= prime1.concat(tempPrimes);
于 2017-10-16T17:24:54.517 回答
0

当您的主要因素数组被排序时,我认为它们是,您可以同时遍历它们。如果其中一个数组头小于另一个,则推进该头并将其推到结果数组。如果两个阵列头相等,则推动头值并推进两个头。这样,您就没有嵌套循环。

以下代码执行此操作并同时创建数组或最小公倍数和最大公约数:

var prime1 = findPrimeFactors(num1);
var prime2 = findPrimeFactors(num2);
var lcm = [];
var gcd = [];

let i = 0;
let j = 0;

while (i < prime1.length && j < prime2.length) {
    if (prime1[i] < prime2[j]) {
        lcm.push(prime1[i++]);
    } else if (prime1[i] > prime2[j]) {
        lcm.push(prime2[j++]);
    } else {
        gcd.push(prime1[i]);
        lcm.push(prime1[i]);
        i++;
        j++;
    }
}

while (i < prime1.length) lcm.push(prime1[i++]);
while (j < prime2.length) lcm.push(prime2[j++]);

解决这个问题的另一种方法是为这两个数字创建一个计数字典。通过将每个键的最大计数添加到结果字典来合并两个字典。此方法不需要排序的素数数组:

var pmax = {};          // result count dict
var pmax2 = {};         // auiliary count dict of primes2

for (let i = 0; i < prime1.length; i++) {
    let p = prime1[i];

    pmax[p] = (pmax[p] || 0) + 1;
}

for (let i = 0; i < prime2.length; i++) {
    let p = prime2[i];

    pmax2[p] = (pmax2[p] || 0) + 1;
}

for (let k in pmax2) {
    pmax[k] = Math.max((pmax[k] || 0), pmax2[k]);
}

for (let k in pmax) {
    let n = pmax[k];

    while (n--) lcm.push(k);
}

最后,计算最小公倍数的最简单方法可能是使用欧几里得算法计算最大公约数并应用关系

lcm(a, b) = a * b / gcd(a, b)

(但要小心,因为该方法可能会导致大量溢出。)

于 2017-10-16T18:58:36.027 回答
0

有一种更简单的方法来获得两个数字的 lcm。我的解决方案很好,但需要更多的工作。

   function lcm(num1, num2){
      for(var i = 1; i <= num1 * num2; i++){
        if(i % num1 === 0 && i % num2 === 0){
          return i;
        }
      }
    }
于 2017-10-18T05:05:15.803 回答