用O(n)求解第七

时间:2018-02-21 03:24:04

标签: javascript algorithm

我已经解决了seventh problem of Euler,它说:

  

通过列出前六个素数:2,3,5,7,11和13,我们可以   看到第6个素数是13。

     

10 001号素数是多少?

我使用了解决它,并且在我保留表兄弟的数组中,当它达到10001的长度时,我返回那个数字。该算法需要 1300 ms ,我认为这是非常低效的,我在实施中特别做了什么?



var start = performance.now();

function eratosthenes(n) {
  var arr = [2], acc = 0; 
// matrix to save the found prime numbers and mark their multiples
  for(var i = 3; true; i += 2) { // loop
    if(arr.length === n) return arr[arr.length - 1]; // if the array length is equal to n return the last number
    if(!resolve(arr, i)) { // check if is multiple of the prime numbers, already found.
      arr.push(i); // if isnt multiple, save it
    }
  }
}

function resolve(array, n) {
  return array.some(cur => !(n%cur));
}
console.log(eratosthenes(10001)); // Tooks 1300 ms

var end = performance.now();
var time = end - start;

console.log(time);




3 个答案:

答案 0 :(得分:3)

Euler筛,Pham知道这一个:) 12ms

Uchu,我不知道你的代码在哪里标记倍数。不是Eratosthenes的Sieve应该做的吗?

JavaScript代码(此代码实际上是对code的改编,通过btilly,优化我的想法):



var start = performance.now();
n = 115000
a = new Array(n+1)
total = 0
s = []
p = 1
count = 0
while (p < n){
  p = p + 1

  if (!a[p]){
    count = count + 1
    if (count == 10001){
      console.log(p);
      end = performance.now();
      time = end - start;

      console.log(time);
      break;
    }
    a[p] = true
    s.push(p)

    limit = n / p
    new_s = []

    for (i of s){
      j = i
      while (j <= limit){
        new_s.push(j)
        a[j*p] = true;
        j = j * p
      }
    }
    s = new_s
  }
}
&#13;
&#13;
&#13;

答案 1 :(得分:2)

根据JaromandaX的要求,这是Eratosthenes筛选的代码。浏览器上51毫秒(OP解决方案是750毫秒)

&#13;
&#13;
var max = 1000000;

function eratosthenes(n) {
   var arr = [], count = 0;
   for (var i = 0; i < max; i++){
   	   arr.push(true);
   }
   for (var i = 2; i < max; i++){
   	   if(arr[i]){
 
   	   	   count++;
   	   	   if(count == n){
 
   	   	   	  return i;
   	   	   } 
   	   	   for (var j = i + i; j < max; j += i ){
   	   	   	    arr[j] = false;
   	   	   }
   	   }
   }
    
}
var start = performance.now(); 
console.log(eratosthenes(10001)); 
var end = performance.now();
var time = end - start;

console.log(time);
&#13;
&#13;
&#13;

答案 2 :(得分:1)

这与גלעדברקן的答案有相似的运行时间(实际上我的机器上的速度提高了大约10%),但在开始之前不依赖于知道大约max。它执行Eratosthenes的最大值(从2开始),然后加倍max,按照先前找到的素数和重复值初始化数组中的新元素。

function eratosthenes(n) {
    let prev_max = 1, max = 2, i, j;
    const primes = [], is_prime = new Array(max+1).fill(true);
    while( true ) {
      for ( i = prev_max + 1; i <= max; i++){
        if ( ! is_prime[i] ) continue;

        primes.push( i );

        if ( primes.length === n )
            return i;

        for ( j = i + i; j <= max; j += i )
            is_prime[j] = false;
      }

      const next_max = max*2;
      is_prime.length = next_max + 1;
      is_prime.fill( true, max + 1, next_max );

      for ( i = 0; i < primes.length; i++ ) {
        const prime = primes[i];
        for ( j = max + prime - max%prime; j <= next_max; j += prime )
          is_prime[j] = false;
      }
      prev_max = max;
      max = next_max;
   }
}

var start = performance.now(); 
console.log(eratosthenes(10001)); 
var end = performance.now();
var time = end - start;

console.log(time);