簡體   English   中英

獲取兩個數組的素因子

[英]Getting the prime factors of two arrays

大家好,我正在嘗試創建一個包含兩個數字的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]沒有重復的數字將被添加到數組中。

如果您需要的只是兩個數組中的唯一項,那么我建議這樣做,

首先將兩個數組連接起來,然后將其存儲在新數組中,

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

當我對主要因子數組進行排序時(我認為是這樣),您可以同時遍歷它們。 如果其中一個數組頭小於另一個數組頭,則將該數組頭前進並將其推入結果數組。 如果兩個陣列頭相等,則推入頭值並前進兩個頭。 這樣,您就沒有嵌套循環。

下面的代碼執行此操作,並同時創建數組或最小公倍數和最大公除數:

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

最后,計算最小公倍數的最簡單方法可能是使用Euclid算法計算最大公除數並應用該關系

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

(但是要小心,因為該方法可能會導致大量溢出。)

有一種更簡單的方法來獲取兩個數字的lcm。 我的解決方案很好,但是還需要更多工作。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM