我解决这个问题的方法很有可能存在缺陷,但我已经接近完成解决方案了。给定数字2和10,我必须找到两个数字中最小公倍数,加上它们范围内的数字。 (2,3,4,5,6,7,8,9,10)
我创建了一个函数,用于返回每个数字的素因子,并将它们推入数组。这就是我失去的地方。我不知道如何减少/过滤掉过多的素数。
我最终应该乘以2 * 2 * 2 * 3 * 3 * 5 * 7,但过滤唯一数字会导致2 * 3 * 5 * 7或2 * 3 * 2 * 5 * 2 * 3 * 7 * 2 * 3 * 2 * 5如果我在数组被压平之前过滤了数字。
function smallestCommons(arr) {
// factorize a number function
function factorization(num) {
let primesArr = [];
// i is what we will divide the number with
for (let i = 2; i <= Math.sqrt(num); i++) {
// if number is divisible by i (with no remainder)
if (num % i === 0) {
// begin while loop that lasts as long as num is divisible by i
while (num % i === 0) {
// change the value of num to be it divided by i
num = num / i;
// push the prime number used to divide num
primesArr.push(i);
}
}
}
// if num is not the number 1 after the for loop
// push num to the array because it is also a prime number
if (num != 1) {
primesArr.push(num);
}
return primesArr;
}
// sort from lowest to highest
arr.sort((a,b) => a - b);
let range = [];
let primeFacts = [];
// push range of numbers to fullArr
for (let i = arr[0]; i <= arr[1]; i++) {
range.push(i);
}
console.log(range); // [2,3,4,5,6,7,8,9,10]
// loop for iterating through range numbers
for (let i = 0; i < range.length; i++) {
// push the prime factors of each range number
primeFacts.push(factorization(range[i]));
}
console.log(primeFacts);
// flatten the array, then return the product of numbers
return primeFacts
.reduce((newArray, arr) => newArray = [...newArray,...arr] ,[])
.reduce((product, num) => product *= num);
};
console.log(smallestCommons([2,10]));
输出
[ 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
[ [ 2 ],[ 3 ],[ 2, 2 ],[ 5 ],[ 2, 3 ],[ 7 ],[ 2, 2, 2 ],[ 3, 3 ],[ 2, 5 ] ]
3628800
如何模拟并将其添加到我的代码中? - &GT; Example of Table I want to emulate
答案 0 :(得分:1)
将此作为主要因素及其学位的表格:
2 3 5 7
2 1
3 1
4 2
5 1
6 2 2
7 1
8 3
9 2
10 1 1
对于LCM,请在每列中取最大度:
3 2 1 1
将这些权力相乘;这是你的答案:
2^3 * 3^2 * 5^1 * 7^1
<强> EXTENSION 强>
要获取GCD,请在每列(包括0)中取最小度。
答案 1 :(得分:0)
你有使用素数分解,还是只需要最低的公倍数?因为有另一个更有效的算法,称为欧几里德算法。你可以在这里阅读:
http://www.programming-algorithms.net/article/42865/Least-common-multiple http://www.programming-algorithms.net/article/43434/Greatest-common-divisor
(注意:通过欧几里德算法计算LCM需要GCD,但也有欧几里德算法)
现在,上面提到的算法适用于两个数字,但我认为(没有经过数学验证,所以你需要自己检查一下)你可以只使用左减少。
最终结果如下所示:
var getLCM = (a, b) => {
// Implement Euclidean LCM algorithm here...
};
var getTotalLCM = (numbers) => {
return numbers.reduce((totalLCM, next) => getLCM(totalLCM, next), 1);
}
var result = getTotalLCM([ 2, 3, 4, 5, 6, 7, 8, 9, 10 ]);
getTotalLCM
将在这里做什么,是否会计算1和2的最小公倍数(1因为这是我们传递给reduce()
的初始累加器值),当然是2.然后它计算LCM为2和3,为6;然后是6和4,它们是12,然后是12和5,它们是60,然后是6和60,它们仍然是60,依此类推。我想这就是你要找的东西?
有关reduce()
如何在这里工作的更多信息:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
答案 2 :(得分:0)
我找到的解决方案。因子分解函数现在返回一个对象而不是主键指数值对。通过in循环和reduce方法,输出LCM。
function smallestCommons(arr) {
// factorize a number function
function factorization(num) {
let primesObj = {};
// i is what we will divide the number with
for (let i = 2; i <= Math.sqrt(num); i++) {
// if number is divisible by i (with no remainder)
if (num % i === 0) {
let exponent = 0;
// begin while loop that lasts as long as num is divisible by i
while (num % i === 0) {
// change the value of num to be it divided by i
num = num / i;
exponent++;
// create key value pair where exponent is the value
primesObj[i] = exponent;
}
}
}
// if num is not the number 1 after the for loop
// push num to the array because it is also a prime number
if (num != 1) {
primesObj[num] = 1;
}
return primesObj;
}
// sort from lowest to highest
arr.sort((a,b) => a - b);
let range = [];
let primeFacts = [];
// push range of numbers to fullArr
for (let i = arr[0]; i <= arr[1]; i++) {
range.push(i);
}
console.log(range); // [2,3,4,5,6,7,8,9,10]
// loop for iterating through range numbers
for (let i = 0; i < range.length; i++) {
// push the prime factors of each range number
primeFacts.push(factorization(range[i]));
}
console.log(primeFacts);
// create a filtered object with only the largest key value pairs
let primeExponents = primeFacts.reduce((newObj,currObj)=> {
for (let prime in currObj) {
// create new key value pair when key value pair does not exist
if (newObj[prime] === undefined) {
newObj[prime] = currObj[prime];
}
// overwrite key value pair when current Object value is larger
else if (newObj[prime] < currObj[prime]) {
newObj[prime] = currObj[prime];
}
}
return newObj;
},{});
let finalArr = [];
// push appropriate amount of primes to arr according to exponent
for (let prime in primeExponents) {
for (let i = 1; i <= primeExponents[prime]; i++) {
finalArr.push(parseInt([prime]));
}
}
return finalArr.reduce((product, num) => product *= num);
};
console.log(smallestCommons([2,10]));
答案 3 :(得分:0)
要从主要分解到LCM,您需要计算每个素数最多需要多少。因此,对于每个因式分解,我将创建一个map
个素数来计算。我会跟踪所需的每个因素的最高数量:
function lcm(primeFacts){
var maxPrimes = {}; // stores the highest number of each prime factor required
for(var i = 0; i < primeFacts.length; i++){
var map = {};
var factors = primeFacts[i];
for(var j = 0; j < factors.length; j++){
// check to see whether the factor already exists in the map
if(map[factors[j]]) map[factors[j]]++;
else map[factors[j]] = 1;
// check to make sure the max count exists
if(!maxPrimes[factors[j]]) maxPrimes[factors[j]] = 1;
if(maxPrimes[factors[j]] < map[factors[j]])
maxPrimes[factors[j]] = map[factors[j]];
}
}
然后,一旦我们掌握了每个因素的所有计数,我们只需将它们相乘:
var multiple = 1;
for(var prime in maxPrimes){
multiple *= prime ^ maxPrimes[prime];
}
}