获得两个数组的主要因素

时间:2017-10-16 17:14:53

标签: javascript arrays algorithm function lcm

大家好我正在尝试创建一个包含两个数字的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]其余的数组没有重复的数字被添加到数组中。

3 个答案:

答案 0 :(得分: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);

答案 1 :(得分: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++]);

另一种解决方法是停止两个数字的计数字典。通过将每个键的最大计数添加到结果字典来合并两个dicts。此方法不需要排序的素因子数组:

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)

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

答案 2 :(得分:0)

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

   function lcm(num1, num2){
      for(var i = 1; i <= num1 * num2; i++){
        if(i % num1 === 0 && i % num2 === 0){
          return i;
        }
      }
    }