【问题标题】:Getting the prime factors of two arrays获取两个数组的素数
【发布时间】:2017-10-16 17:14:53
【问题描述】:

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

【问题讨论】:

    标签: javascript arrays algorithm function lcm


    【解决方案1】:

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

    先将两个数组串联起来,存入一个新的数组中,本例中,

    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);
    

    【讨论】:

    • 我还需要包含重复项。所以如果我有一个数组是:[2,2,2,3],另一个是[2, 13]。那么我的新数组应该是[2, 2, 2, 3, 13]
    • 嗯,如果是 [2,2,2,3] 而另一个是 [2,2,13] 怎么办?你还想要 [2, 2, 2, 3, 13] 吗?
    • 是的,[2, 2, 13] 是 52,52 和 24 的 lcm 仍然是 312,所以是的。
    • 编辑了答案
    【解决方案2】:

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

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

    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)
    

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 2011-01-20
        • 1970-01-01
        • 1970-01-01
        • 2023-02-16
        • 2020-06-08
        • 2014-06-16
        • 2020-02-23
        • 2021-05-19
        • 1970-01-01
        相关资源
        最近更新 更多