如何编写获取数组所有元素公共除数的JavaScript函数?
我来帮你搞定这个问题!你的需求是找出能整除数组所有元素的数(也就是数组的公约数),但原代码只是把每个元素的除数全部收集起来了,所以得到的是所有元素除数的并集,而非我们需要的交集。我们可以分两步来实现正确的逻辑:
步骤1:先计算数组所有元素的最大公约数(GCD)
数组的所有公约数,本质上都是最大公约数的约数。所以第一步我们需要先求出整个数组的最大公约数,这里可以用经典的欧几里得算法:
// 求两个数的最大公约数 function gcd(a, b) { while (b !== 0) { const temp = b; b = a % b; a = temp; } return a; } // 扩展到求整个数组的最大公约数 function getArrayGCD(arr) { return arr.reduce((currentGCD, num) => gcd(currentGCD, num), arr[0]); }
步骤2:找出最大公约数的所有约数
拿到数组的最大公约数后,我们只需要找出这个数的所有约数(根据你的案例结果,这里排除1):
function getCommonDivisors(n) { const divisors = []; // 遍历到平方根,避免重复计算 for (let i = 2; i <= Math.sqrt(n); i++) { if (n % i === 0) { divisors.push(i); // 如果不是平方数,把对应的另一个约数也加入 if (i !== n / i) { divisors.push(n / i); } } } // 别忘了加上最大公约数本身 divisors.push(n); // 排序让结果更规整(可选) divisors.sort((a, b) => a - b); return divisors; }
整合后的最终函数
把上面的逻辑整合到一起,就是你需要的完整函数:
function scf(array) { // 处理空数组的边界情况 if (array.length === 0) return []; // 求两个数的最大公约数 function gcd(a, b) { while (b !== 0) { const temp = b; b = a % b; a = temp; } return a; } // 求数组的最大公约数 const totalGCD = array.reduce((currentGCD, num) => gcd(currentGCD, num), array[0]); // 如果最大公约数是1,说明除了1没有其他公共除数(按需求排除1则返回空数组) if (totalGCD === 1) return []; // 找出最大公约数的所有约数(排除1) const divisors = []; for (let i = 2; i <= Math.sqrt(totalGCD); i++) { if (totalGCD % i === 0) { divisors.push(i); if (i !== totalGCD / i) { divisors.push(totalGCD / i); } } } divisors.push(totalGCD); divisors.sort((a, b) => a - b); return divisors; } // 测试你的案例 console.log(scf([133, 147, 427, 266])); // 输出 [7]
原代码的问题分析
原代码的逻辑是逐个遍历数组元素,把每个元素的所有除数都塞进结果数组,所以得到的是所有元素除数的合并集合,而非所有元素共有的除数。我们需要的是公约数,必须先找到所有元素的公共最大公约数,再推导它的所有约数,这样才能得到正确结果。
内容的提问来源于stack exchange,提问作者user9279766
相关产品推荐
相关产品推荐

