我编写了一个算法,它返回两个整数的最小公倍数,可以被两者平均分割,也可以在初始两个整数之间的范围内均匀地除以所有序列整数。
我的算法适用于最小公倍数是一个相当低的数字的数字。对于最小公倍数是一个非常大的数字(例如[1,13]其360360),我的算法会中断,因为它依赖于越来越多的循环运行。
我在下面发布了我的代码。它似乎很长,但问题部分接近开头,其余代码是为上下文添加的。
是否有更有效的解决方案,运行越来越多的循环迭代以返回更大的数字?
// If mystery failure occurs, examine i & j loop limits.
function smallestCommons(arr) {
var firstArray = [];
var secondArray = [];
var commonNums = [];
var sequential = [];
// Sort the array from lowest to highest
arr.sort(function(a,b) {
return a-b;
});
// Assing arr values to vars so that original data stays intact
var array0 = arr[0];
var array1 = arr[1];
//console.log(arr);
// Find all multiples of both inputs.
// THIS IS THE PROBLEM SECTION
for (var i = 0; i < 1000000; i++) {
firstArray.push(arr[0] * (i+1));
}
for (var j = 0; j < 1000000; j++) {
secondArray.push(arr[1] * (j+1));
}
// THAT WAS THE PROBLEM SECTION
// Find common multiples.
for (var k = 0; k < firstArray.length; k++) {
for (var l = 0; l < secondArray.length; l++) {
if (firstArray[k] == secondArray[l]) {
commonNums.push(firstArray[k]);
} // End if.
} // End l loop.
} // End k loop.
// Find sequential numbers in range between input parameters.
for (var m = 0; m < array1; m++) {
if (array0 + 1 !== array1) {
sequential.push(array0 += 1);
} // End of if.
} // End of m loop.
// Find commonNums divisible by arr && sequential to produce a whole number.
// commonNums [ 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75]
// arr [1,5]
// sequential [ 2, 3, 4 ]
for (var n = 0; n < commonNums.length; n++) {
var match = true;
for (var o = 0; o < sequential.length; o++) {
for (var p = 0; p < arr.length; p++) {
if (commonNums[n] % arr[p] !== 0 || commonNums[n] % sequential[o] !== 0) {
match = false;
}
}
}
if(match) {
console.log(commonNums[n]);
}
} // End of n loop.
} // End function.
smallestCommons([1,13]);
答案 0 :(得分:1)
你做的事情没有多大意义,而且很难阅读。解决这个问题你需要知道的只是一点数学。这个数学告诉你:
lcm(a, b) = a * b / gcd(a, b)
lcm(a,b,c) = lcm(a,lcm(b,c))
翻译成这样的东西:
function gcd(a, b){
while (b !== 0) {
var tmp = a;
a = b;
b = tmp % b;
}
return a
}
function lcm(a, b){
return a * b / gcd(a, b);
}
function lcm_arr(arr){
var res = 1;
for (var i = 0; i < arr.length; i++){
res = lcm(res, arr[i]);
}
return res;
}
在不到一秒的时间内为您提供结果:
lcm_arr([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13])
答案 1 :(得分:0)
听起来像是一个使用recursion的好地方,因为当数字差异为1时(例如trends/place
或trends/place
取决于方向),您有一个坚实的基本情况,其余(序列)将递增较小或递减递归调用中较大的数字。这可以节省你很多CPU周期。