Javascript for loop 在计算 LCM 时出现无限循环错误
Javascript for loop giving infinite loop error while calculating LCM
我要解决的问题是计算给定数字范围的最小公倍数。
数组中提供的数字可以按任何顺序排列,但 attay 将只有两个数字。
我的代码适用于 [1,5] 、 [1,10]、[1,12] 对,但是一旦我尝试 [1,13] 我就会遇到无限循环错误并且答案变得不确定。
对于以下代码,预期答案是 360360
function smallestCommons(arr) {
var a = arr[0];
var b = arr[1];
var start = 0;
var end = 0;
if (a<b) {
start=a;
end=b;
}
else {
start=b;
end=a;
}
//console.log("Start:"+start);
//console.log("End:"+end);
var numArray = [];
for(let i=start; i<end+1; i++) {
numArray.push(i);
}
console.log(numArray);
var oddArray = [];
var product = numArray.reduce((a,b)=>a=a*b);
console.log("Product:"+product);
console.log(numArray[0]);
var result = 0;
console.log(result);
//let j=numArray[0];
for(let j=numArray[0];j<=product;j++) {
var count = 0;
for(let k=0;k<numArray.length; k++) {
if(j%numArray[k]==0) {
count++;
}
}
if(count==numArray.length) {
return j;
}
}
}
console.log(smallestCommons([1,13]));
它应该是 product.length-1 因为 reduce returns 一个数组
for(let j=numArray[0];j<=product.length-1;j++) {
你的做法是错误的。
1、2、3、4的LCM是多少?它是 12,因为它是 3 x 4。
您的代码将做什么:
var product = numArray.reduce((a,b)=>a=a*b); // product will be 24
...
for(let j=numArray[0];j<=product;j++) { // iterate from 1 -> 24
var count = 0;
for(let k=0;k<numArray.length; k++) { // iterate from 0 -> 3
if(j%numArray[k]==0) { // consider it a hit if j is divisible by an element
count++;
}
}
if(count==numArray.length) { // on the 4th "hit"
return j; // return j which is a number between 1 -> 24
}
}
如果您 运行 陷入无限循环,那是因为您没有获得正确的点击次数。
解决 LCM 问题的正确方法是考虑质因数。
让我们再次使用 1、2、3、4。
对于每个数字,我得到一个质因数。
1 -> 1(1)
2 -> 2(1), 1(1)
3 -> 3(1), 1(1)
4 -> 2(2), 1(1)
我们通过对每个素因子使用 max(cnt) 来减少这个集合。
1的最大计数是1。2的最大计数是2。3的最大计数是1。
所以我们然后去:2 x 2 x 3 = 12,这就是我们的答案。
这需要 2 遍:
- 首先遍历数字数组。
- 第二次通过素数计数图。
...我的方式:
function isPrime(n)
{
if(n < 2) return false
for (let x = 2; x < n; ++x) if (n%x===0) return false
return true
}
function smallestCommons(range)
{
let nMin = Math.min(...range)
, nTab = []
, xPow = {}
;
for (let n = Math.max(...range); n >1; --n)
{
if (n>=nMin && !(nTab.find(x=>(x%n===0))) ) nTab.push(n)
if (isPrime(n))
{
nTab.forEach(v=>
{
if(v%n===0)
{
let p = 0
while ((v%(n**++p))===0) {}
--p
if ( !xPow[n] ) xPow[n] = p
else xPow[n] = Math.max(xPow[n], p)
}
})
}
}
return Object.entries(xPow).reduce((a,[v,p])=>a*(v**p),1)
}
console.log ('[1,4] ->', smallestCommons([1,4]) )
console.log ('[1,5] ->', smallestCommons([1,5]) )
console.log ('[1,10] ->', smallestCommons([1,10]) )
console.log ('[1,12] ->', smallestCommons([1,12]) )
console.log ('[1,13] ->', smallestCommons([1,13]) )
我要解决的问题是计算给定数字范围的最小公倍数。 数组中提供的数字可以按任何顺序排列,但 attay 将只有两个数字。
我的代码适用于 [1,5] 、 [1,10]、[1,12] 对,但是一旦我尝试 [1,13] 我就会遇到无限循环错误并且答案变得不确定。
对于以下代码,预期答案是 360360
function smallestCommons(arr) {
var a = arr[0];
var b = arr[1];
var start = 0;
var end = 0;
if (a<b) {
start=a;
end=b;
}
else {
start=b;
end=a;
}
//console.log("Start:"+start);
//console.log("End:"+end);
var numArray = [];
for(let i=start; i<end+1; i++) {
numArray.push(i);
}
console.log(numArray);
var oddArray = [];
var product = numArray.reduce((a,b)=>a=a*b);
console.log("Product:"+product);
console.log(numArray[0]);
var result = 0;
console.log(result);
//let j=numArray[0];
for(let j=numArray[0];j<=product;j++) {
var count = 0;
for(let k=0;k<numArray.length; k++) {
if(j%numArray[k]==0) {
count++;
}
}
if(count==numArray.length) {
return j;
}
}
}
console.log(smallestCommons([1,13]));
它应该是 product.length-1 因为 reduce returns 一个数组
for(let j=numArray[0];j<=product.length-1;j++) {
你的做法是错误的。
1、2、3、4的LCM是多少?它是 12,因为它是 3 x 4。
您的代码将做什么:
var product = numArray.reduce((a,b)=>a=a*b); // product will be 24
...
for(let j=numArray[0];j<=product;j++) { // iterate from 1 -> 24
var count = 0;
for(let k=0;k<numArray.length; k++) { // iterate from 0 -> 3
if(j%numArray[k]==0) { // consider it a hit if j is divisible by an element
count++;
}
}
if(count==numArray.length) { // on the 4th "hit"
return j; // return j which is a number between 1 -> 24
}
}
如果您 运行 陷入无限循环,那是因为您没有获得正确的点击次数。
解决 LCM 问题的正确方法是考虑质因数。 让我们再次使用 1、2、3、4。
对于每个数字,我得到一个质因数。
1 -> 1(1)
2 -> 2(1), 1(1)
3 -> 3(1), 1(1)
4 -> 2(2), 1(1)
我们通过对每个素因子使用 max(cnt) 来减少这个集合。 1的最大计数是1。2的最大计数是2。3的最大计数是1。 所以我们然后去:2 x 2 x 3 = 12,这就是我们的答案。
这需要 2 遍:
- 首先遍历数字数组。
- 第二次通过素数计数图。
...我的方式:
function isPrime(n)
{
if(n < 2) return false
for (let x = 2; x < n; ++x) if (n%x===0) return false
return true
}
function smallestCommons(range)
{
let nMin = Math.min(...range)
, nTab = []
, xPow = {}
;
for (let n = Math.max(...range); n >1; --n)
{
if (n>=nMin && !(nTab.find(x=>(x%n===0))) ) nTab.push(n)
if (isPrime(n))
{
nTab.forEach(v=>
{
if(v%n===0)
{
let p = 0
while ((v%(n**++p))===0) {}
--p
if ( !xPow[n] ) xPow[n] = p
else xPow[n] = Math.max(xPow[n], p)
}
})
}
}
return Object.entries(xPow).reduce((a,[v,p])=>a*(v**p),1)
}
console.log ('[1,4] ->', smallestCommons([1,4]) )
console.log ('[1,5] ->', smallestCommons([1,5]) )
console.log ('[1,10] ->', smallestCommons([1,10]) )
console.log ('[1,12] ->', smallestCommons([1,12]) )
console.log ('[1,13] ->', smallestCommons([1,13]) )