[英]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.