我正在编写一个程序,该程序将埃拉托色尼筛法执行到给定的限制。这是当前的代码:
const { isPrime } = require(`./numPropFuncs.js`);
const limit = 30;
const primes = [];
const eratosthenesSieve = num => {
for (let i = 0; i <= num; i++) {
if (isPrime(i)) {
primes.push(i);
};
};
};
eratosthenesSieve(limit);
console.log(primes.join(`, `);
它导入以下模块来测试数字是否为素数:
const resources = require(`./factorList.js`);
const isPrime = num => {
resources.factorList(num);
if (resources.factors.length === 2) {
return true;
} else {
return false;
};
};
依次导入以下模块,该模块提供给定数字的所有因子的数组:
const factors = [];
const factorList = (num) => {
for (let i = 0; i <= num; i++) {
if (num % i === 0) {
factors.push(i);
};
};
};
两个模块都经过测试,以确保它们工作并已正确导入。 问题是,当在
isPrime()
的 for 循环内调用 eratosthenesSieve()
时,它会在每次迭代时返回 false
,包括素数时作为参数传递。
我正在测试
eratosthenesSieve()
,使用 30 作为限制,因为这样很容易验证结果。记录的输出应该是字符串:2, 3, 5, 7, 11, 13, 17, 19, 23, 29
。相反,它要么不记录任何内容,或者在记录 primes
而不记录 .join()
的情况下,[]。每次迭代都有循环日志 ${i}: ${isPrime(i)}
后,我意识到 isPrime()
为每个数字返回 false
(即记录“0:假”...“30:假”)。我在 isPrime()
之外和 eratosthenesSieve()
内部测试了 eratosthenesSieve()
,但在 for 循环之外,两次都工作正常。
我认为这可能是一个范围问题,所以我尝试使用一个单独的变量,在
eratosthenesSieve()
内部但在循环外部声明,作为测试编号而不是 i:
const eratosthenesSieve = num => {
let testNumber = 0;
for (let i = 0; i <= num; i++) {
if (isPrime(testNumber)) {
primes.push(testNumber);
};
testNumber++;
};
};
这解决了我在另一个程序的循环中遇到的另一个问题,尽管该程序没有使用
isPrime()
(我不记得该程序的问题是什么)。然而,这个解决方案不适用于埃拉托色尼筛程序。
我尝试在每次迭代中简单地记录
${7}: ${isPrime(7)}
,同时注释掉eratosthenesSive()
中的其余代码,只是为了看看会发生什么。奇怪的是,它在第一次迭代时记录了 7: true
(显然是正确的输出),但在 29 个连续迭代中的每一次都记录了 7: false
。
最后,我尝试重构,让循环从 1 开始,以防从 0 开始导致问题。这也没有帮助。
我不知道这里发生了什么以及如何解决它。预先非常感谢您的帮助。 (我的运行环境是 MacOS Sonoma 上 VS code 中的 Node.js)
您正在为
factors
函数的每次调用修改 isPrime()
数组,而无需重置它。因为它是全局的,所以即使在 isPrime()
/factorsList()
函数执行完成后,您推入其中的值仍然会保留。例如,如果您调用 isPrime(1)
,则 resources.factors
更新为:
[1]
然后在下一次迭代中,您调用
isPrime(2)
,这会导致将 1
和 2
推送到上一个结果上,现在 resources.factors
将是:
[1, 1, 2]
从这里开始,
resources.factors
不断增长,这意味着您的resources.factors.length === 2
签到isPrime()
永远不会是true
。
相反,使
factors
成为 factorsList
函数的本地函数,以便对 factorsList
的每次调用都是独立的,并仅针对该调用返回 factors
:
const factorList = (num) => {
const factors = [];
for (let i = 0; i <= num; i++) {
if (num % i === 0) {
factors.push(i);
}
}
return factors;
};
然后您可以在
isPrime
函数中使用返回的数组:
const isPrime = (num) => {
const factors = resources.factorList(num);
return factors.length === 2;
};