JS中While循环未过滤毕达哥拉斯三元组重复项问题排查
毕达哥拉斯三元组去重失败的原因与修复方案
你猜的没错,问题核心就出在pyTrips[i] !== temp这个数组比较环节。
在JavaScript中,数组属于引用类型——哪怕两个数组的内容完全一模一样,只要它们不是同一个内存地址的引用,用===或!==比较都会返回false。举个例子:
const arr1 = [3,4,5]; const arr2 = [3,4,5]; console.log(arr1 !== arr2); // 输出true
你的代码里每次生成的temp都是新创建的数组对象,所以pyTrips[i] !== temp永远为true,导致while循环会一直执行到i === pyTrips.length,最终每次都会把temp推入数组,自然出现重复结果。
修复方案
有两种简单的方法可以解决这个问题:
方法1:对比数组内容而非引用
写一个辅助函数,遍历数组元素逐一对比是否完全一致:
function arraysEqual(arr1, arr2) { if (arr1.length !== arr2.length) return false; for (let j = 0; j < arr1.length; j++) { if (arr1[j] !== arr2[j]) return false; } return true; }
然后把while循环的条件修改为:
while (i < pyTrips.length && !arraysEqual(pyTrips[i], temp)) { i++; }
方法2:将数组转为字符串后对比
相同内容的数组转为字符串后是完全一致的,比如[3,4,5].toString()结果为"3,4,5",直接对比字符串即可:
while (i < pyTrips.length && pyTrips[i].toString() !== temp.toString()) { i++; }
修改后的完整代码示例(以方法1为例)
var a, b, c, i, pyTrips, temp; pyTrips = new Array(); temp = new Array(); function arraysEqual(arr1, arr2) { if (arr1.length !== arr2.length) return false; for (let j = 0; j < arr1.length; j++) { if (arr1[j] !== arr2[j]) return false; } return true; } for (a = 1; a <= 10; a++) { for (b = 1; b <= 10; b++) { c = Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2)); if (c % 1 === 0) { temp = a < b ? [a, b, c] : [b, a, c]; i = 0; while (i < pyTrips.length && !arraysEqual(pyTrips[i], temp)) { i++; } if (i === pyTrips.length) { pyTrips.push(temp); } console.log(pyTrips.toString()); } } }
(注:这里去掉了with(Math),因为它会影响代码性能和可读性,直接调用Math上的方法更规范)
内容的提问来源于stack exchange,提问作者DKqwerty
相关产品推荐
相关产品推荐

