javascript - Javascript - 素数函数问题,内存过载
问题描述
我有下一个问题。我试图找到所有素数,直到指定的数字作为输入,但是当我输入例如非常大的数字(例如 13480000 或 643513511)时,算法会以某种方式停止迭代,并且我的浏览器在处理函数方面变得太慢. 这是html代码:
<!DOCTYPE html>
<html lang="es">
<head>
<script src="esPrimo.js">
</script>
</head>
<body>
<h1>Lista de primos</h1>
<form name="formu">
<input id="txtValue" type="text" />
<input type="button" value="Calcular!" onclick="proceso()">
</form>
<p id="res">El resultado se escribe aqui</p>
</body>
</html>
这是我的 esPrimo.js 文件的 javascript 代码
function proceso() {
var value = document.querySelector('#txtValue').value;
var primos = getPrimos(value);
var output = document.querySelector('#res');
output.innerHTML = primos.toString();
}
function getPrimos (value) {
var primos = [];
for (var i = 1; i <= value; i++){
if (esPrimo(i)) primos.push(i);
}
return primos;
}
function esPrimo(n){
if (isNaN(n) || !isFinite(n) || n%1 || n<2) return false;
var m = Math.sqrt(n);
for (var i = 2; i <= m; i++)
if (n % i == 0) return false;
return true;
}
在程序获取参数的最后一个函数上,变得非常慢。它检查 n 是否可以被每个整数 2、3、4、5 ... 整除,直到 sqrt(n),但这个版本的代码行数最少。此外,我尝试了另一种遍历所有素数的方法,例如:
function esPrimo(n) {
if (isNaN(n) || !isFinite(n) || n%1 || n<2) return false;
if (n%2==0) return (n==2);
var m=Math.sqrt(n);
for (var i=3;i<=m;i+=2) {
if (n%i==0) return false;
}
return true;
}
在这里,它分别检查除数 2:然后,它只检查奇数除数,从 3 到 sqrt(n)。最多检查 3 和 sqrt(n) 之间的数字的一半。
我怎样才能优化代码,以便我的程序能够更快地计算这种迭代?
任何建议或建议,这将是非常感激和有帮助的,因为我在过去一周一直试图以某种方式找到解决方案,但它没有用。此外,我还有最后一个感兴趣的链接,我深入研究并帮助了我很多,我想说的是在掌握数字的素性检验方面。
谢谢
解决方案
与 Pointy 在评论中所说的不同,下面是您的 JavaScript 重构以使用 Eratosthenes “筛子”算法。在我进入代码之前,首先快速解释一下 Erastosthenes。Erastosthenes 发现您可以更有效地找到介于 2 和 N 之间的素数,其中 N 是一个大数,方法是找到两者之间每个数字的倍数并将它们从列表中删除。你剩下的东西一定是素数。
EG N = 10
2、3、4、5、6、7、8、9、10 --> 2 的倍数包括 4、6、8 和 10,所以它们不是素数。3 的倍数包括 6 和 9,因此它们被删除。等等。你最终只剩下 2、3、5、7,其中没有一个有一个数字相乘。
现在,下面的代码使用了 Erastosthenes 算法,但是如果你尝试你的 643513511 的例子,它仍然会中断,我只是觉得浏览器需要的处理能力太多了,但我可能错了。但是,它适用于您的 1300 万示例。
注意:此代码是使用您的代码和从另一篇 Stackoverflow 帖子中获取的代码重构的,即 Sieve of Eratosthenes algorithm in JavaScript running never for large number。
var getPrimos = function(n) {
// Eratosthenes algorithm to find all primes under n
var array = [], upperLimit = Math.sqrt(n), output = [];
// Make an array from 2 to (n - 1)
for (var i = 0; i < n; i++) {
array.push(true);
}
// Remove multiples of primes starting from 2, 3, 5,...
for (var i = 2; i <= upperLimit; i++) {
if (array[i]) {
for (var j = i * i; j < n; j += i) {
array[j] = false;
}
}
}
// All array[i] set to true are primes
for (var i = 2; i < n; i++) {
if(array[i]) {
output.push(i);
}
}
return output;
};
推荐阅读
- django - 如何在 Django 中记录请求和响应?
- javascript - 如果匹配某个单词,如何删除字符串的最后一个单词?
- python-3.x - 使用jupyter在熊猫中应用过滤器,但没有记录只有标题显示
- c# - 创建表达式
从带有重载构造函数的方法名 - python - 为什么当 Python Sklearn 中的列大于行时它会起作用(线性回归)
- sql - 如果目标表具有 GENERATE ALWAYS AS IDENTITY COLUMN,Oracle 是否允许 SQL INSERT INTO 对 VALUES 使用 SELECT 语句
- sql - 如何使用 case 语句在 sql 中返回不同的 pull?
- c# - c# 进度条在第二次运行时从旧值开始
- bash - 在 Ubuntu 中转换音频文件的采样率的脚本
- python - pastebin api:无效的 api_dev_key