我正在写一个程序,它将埃拉托斯提尼的筛分执行到给定的限制.这是当前的代码:

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);
    };
  };
};

Both modules have been tested to ensure they work and have been imported properly.问题是,当在eratosthenesSieve()的for循环内调用isPrime()时,它为每次迭代返回false,包括将素数作为参数传递时.

我正在测试eratosthenesSieve(),使用30作为限制,因为很容易验证结果.记录的输出应为字符串:2, 3, 5, 7, 11, 13, 17, 19, 23, 29.相反,它不记录任何内容,或者在记录primes而不记录.join()的情况下,[].在每次迭代的循环日志(log)${i}: ${isPrime(i)}之后,我意识到isPrime() for each 数字返回false(即记录"0:False"..."30:False").我在eratosthenesSieve()外测试了isPrime(),在eratosthenesSieve()内测试了isPrime(),但在for循环之外,两次都工作正常.

我想这可能是一个作用域问题,所以我try 使用一个单独的变量,声明在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次.

最后,我try 了重构,使循环从1开始,以防从0开始引起问题.这也无济于事.

我不知道这里发生了什么,也不知道如何修复它.提前感谢您的帮助.(我的运行时环境是MacOS Sonoma上的VS代码中的Node.js)

推荐答案

您正在为isPrime()函数的每次调用修改factors数组,而无需重置它.因为factors是全局的,所以即使在isPrime()/factorsList()函数执行完之后,您放入其中的值也会保持不变.例如,如果您呼叫isPrime(1),则resources.factors将更新为:

[1]

然后在下一次迭代中,你调用isPrime(2),这导致将12推到前一个结果上,现在resources.factors将是:

[1, 1, 2]

从现在开始,resources.factors会继续增长,这意味着你在isPrime()登记的resources.factors.length === 2永远不会是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;
};

module.exports.factorList = factorList;

然后,您可以在isPrime函数中使用返回的数组:

const isPrime = (num) => {
  const factors = resources.factorList(num);
  return factors.length === 2;
};

Javascript相关问答推荐

如何按预期聚合SON数据?

如何提取Cypress中文本

通过在页面上滚动来移动滚动条

react/redux中的formData在expressjs中返回未定义的req.params.id

类型脚本中只有字符串或数字键而不是符号键的对象

如何禁用附加图标点击的v—自动完成事件

分层树视图

CheckBox作为Vue3中的一个组件

setcallback是什么时候放到macrotask队列上的?

如何使用子字符串在数组中搜索重复项

Reaction Native中的范围滑块

React.Development.js和未捕获的ReferenceError:未定义useState

在开发期间,Web浏览器如何运行&qot;.jsx&qot;文件?

Reaction-SWR-无更新组件

Phaserjs-创建带有层纹理的精灵层以自定义外观

Reaction useState和useLoaderData的组合使用引发无限循环错误

在JavaScript中将Base64转换为JSON

按特定顺序将4个数组组合在一起,按ID分组

更新文本区域行号

JavaScript -如何跳过某个字符(S)来打乱字符串中的字符