算法";埃拉托斯烯筛“;通过javascript
该代码是否为埃拉托斯烯筛的示例实现?算法";埃拉托斯烯筛“;通过javascript,javascript,sieve-of-eratosthenes,Javascript,Sieve Of Eratosthenes,该代码是否为埃拉托斯烯筛的示例实现? 这个实现的复杂性是什么 UPD: 我使用数组项构建计数操作图表。我认为复杂性是O(n)。我说得对吗? console.time('exec'); var-arr=fn(数学功率(10,2)); console.timeEnd('exec'); 函数fn(n){ var arr=Array.apply(null,{length:n+1}).map(函数(){return true;}); arr[0]=arr[1]=false; var基数=2; while(
这个实现的复杂性是什么 UPD: 我使用数组项构建计数操作图表。我认为复杂性是
O(n)
。我说得对吗?
console.time('exec');
var-arr=fn(数学功率(10,2));
console.timeEnd('exec');
函数fn(n){
var arr=Array.apply(null,{length:n+1}).map(函数(){return true;});
arr[0]=arr[1]=false;
var基数=2;
while(数学功率(基数,2) });代码>运行时复杂性为O(n*n),因为您迭代base并向上计数到所需的值n
(在循环的比较中,您错过了最后一个值)
console.time('exec');
函数fn(n){
var arr=Array.from({length:n+1},({,i)=>i>1),
基数=2,
柜台
while(Math.pow(base,2)运行时复杂度为O(n*n),因为您迭代base并向上计数到想要的值n
(在循环的比较中,您错过了最后一个值)
console.time('exec');
函数fn(n){
var arr=Array.from({length:n+1},({,i)=>i>1),
基数=2,
柜台
而(Math.pow(base,2)算法的渐近时间复杂度,我认为,O(nlogn)
外部循环运行2…sqrt(n)
。内部循环运行n/base
次,其中base
在2…sqrt(n)
的外部范围内
运行循环会导致总迭代计数,可表示为:
(1)(n/2)+(n/3)+(n/4)+…+(n/sqrt(n))
上面的括号用于表示外循环的单个迭代中内循环的迭代计数
我们可以提取n
并获得
(2)n*(1/2+1/3+1/4+…+1/sqrt(n))
括号中的项是已知发散的调和级数,因此我们没有得到像O(1)这样的好结果,尽管发散非常缓慢。这也被你的线性图表从经验上证明了
结果表明,谐波级数与ln(n)
()具有常数关系
因此,我们得到了n*ln(n)
,从而得到了O(n logn)的复杂性
你没有得到更好的O(n log n)复杂性,因为你的解决方案没有使用素数分解(因此素数调和级数是O(log n)())
实际上,这是因为您的算法检查非素数,例如,arr[counter*base]=false;为base
和counter
对{2,6}、{3,4}、{4,3}、{6,2}分配了相同的索引,但是base
4和6在应用时已经知道不是素数,根据算法的定义,它们的所有倍数也已经知道不是素数,因此再次检查它们是无用的
编辑
O(n log n)JavaScript实现可能如下所示:
function sieve(n)
{
// primes[x] contains a bool whether x is a prime
const primes = new Array(n + 1).fill(true);
// 0 and 1 are not primes by definition
primes[0] = false;
primes[1] = false;
function square(i)
{
return i * i;
}
for (let number = 2; square(number) <= n; number += 1)
{
if (!primes[number])
{
// we have already determined that the number is not a prime
// therefore all its multiples are also already determined not to be primes
// skip it
continue;
}
for (let multiplier = 2; multiplier * number <= n; multiplier += 1)
{
// a multiple of prime is not a prime
primes[multiplier * number] = false;
}
}
return primes;
}
功能筛(n)
{
//素数[x]包含一个布尔值,无论x是素数
常量素数=新数组(n+1).fill(真);
//根据定义,0和1不是素数
素数[0]=假;
素数[1]=假;
功能广场(一)
{
返回i*i;
}
对于(设number=2;square(number),我认为算法的渐近时间复杂度是,O(nlogn)
外部循环运行2…sqrt(n)
。内部循环运行n/base
次,其中base
在2…sqrt(n)
的外部范围内
运行循环会导致总迭代计数,可表示为:
(1)(n/2)+(n/3)+(n/4)+…+(n/sqrt(n))
上面的括号用于表示外循环的单个迭代中内循环的迭代计数
我们可以提取n
并获得
(2)n*(1/2+1/3+1/4+…+1/sqrt(n))
括号中的项是已知发散的调和级数,因此我们没有得到像O(1)这样的好结果,尽管发散非常缓慢。这也被你的线性图表从经验上证明了
结果表明,谐波级数与ln(n)
()具有常数关系
因此,我们得到了n*ln(n)
,从而得到了O(n logn)的复杂性
你没有得到更好的O(n log n)复杂性,因为你的解决方案没有使用素数分解(因此素数调和级数是O(log n)())
实际上,这是因为您的算法检查非素数,例如,arr[counter*base]=false;为base
和counter
对{2,6}、{3,4}、{4,3}、{6,2}分配了相同的索引,但是base
4和6在应用时已经知道不是素数,根据算法的定义,它们的所有倍数也已经知道不是素数,因此再次检查它们是无用的
编辑
O(n log n)JavaScript实现可能如下所示:
function sieve(n)
{
// primes[x] contains a bool whether x is a prime
const primes = new Array(n + 1).fill(true);
// 0 and 1 are not primes by definition
primes[0] = false;
primes[1] = false;
function square(i)
{
return i * i;
}
for (let number = 2; square(number) <= n; number += 1)
{
if (!primes[number])
{
// we have already determined that the number is not a prime
// therefore all its multiples are also already determined not to be primes
// skip it
continue;
}
for (let multiplier = 2; multiplier * number <= n; multiplier += 1)
{
// a multiple of prime is not a prime
primes[multiplier * number] = false;
}
}
return primes;
}
功能筛(n)
{
//素数[x]包含一个布尔值,无论x是素数
常量素数=新数组(n+1).fill(真);
//根据定义,0和1不是素数
素数[0]=假;
素数[1]=假;
功能广场(一)