关于jscript:需要在JavaScript中生成质数

Need to generate prime numbers in JavaScript

我正在编写JavaScript以生成2到100的质数。但是,它不起作用,无法弄清楚。

你能帮我吗?

1
2
3
4
5
6
7
var array = new Array(100);

for (var i=2 ; i<=array.length-1; i++) {
    if((i%2===0) || (i%3===0))
        continue;
    document.writeln(i+",");
}

我修改了答案,但现在不打印2&3; 我如何包含2和3 ...
结果是:

5, 7, 11, 13, 17, 19, 23, 25, 29, 31, 35, 37, 41, 43, 47, 49, 53, 55, 59, 61, 65, 67, 71, 73, 77, 79, 83, 85, 89, 91, 95, 97


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function isPrime(num) {
    for ( var i = 2; i < num; i++ ) {
        if ( num % i === 0 ) {
            return false;
        }
    }
    return true;
}

function display(n) {
    var arr = [2];
    for ( var i = 3; i < n; i+=2 ) {
        if ( isPrime(i) ) {
            arr.push(i);
        }
    }
    console.log(arr); // use arr result on your own
}

display(100);

注意:在显示功能中指定n参数,并将质数从2改为n ...

看看JSFiddle

更新:请注意,上面的脚本是正确的,尽管我添加了相同的功能和一个功能,但我将其保留:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function prime(n,flag) {
    ( typeof flag ==="undefined" || flag === false ) ? flag = false : flag = true;

    function isPrime(num) {
        if ( num === 0 || num === 1 ) {
            return false;
        }
        for ( var i = 2; i < num; i++ ) {
            if ( num % i === 0 ) {
                return false;
            }
        }
        return true;
    }

    if ( flag ) {
        var arr = [2];
        for ( var i = 3; i <= n; i+=2 ) {
            if ( isPrime(i) ) {
                arr.push(i);
            }
        }
        return arr;
    } else {
        return isPrime(n);
    }
}

说明:prime函数需要两个参数,第一个是必需的,第二个是可选的。如果仅指定第一个参数,则函数将根据数字是否属于素数返回truefalse。如果将第二个参数指定为true(或undefinedfalse以外的任何其他类型),函数将把array的质数从2返回到n。例如:

1
2
3
4
console.log(prime(2)); // returns true ( 2 is prime )
console.log(prime(8)); // returns false ( 8 isn't prime )

console.log(prime(100,true)); // returns [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]


使用javascript生成器的版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function* take(length, iterable) {
  for (let x of iterable) {
    if (length <= 0) return;
    length--;
    yield x;
  }
}

function* primes() {
  let n = 2;

  while (true) {
    if (isPrime(n)) yield n;
    n++;
  }

  function isPrime(num) {
    for (var i = 2; i <= Math.sqrt(num); i++) {
      if (num % i === 0) {
        return false;
      }
    }
    return true;
  }
}

console.log([...take(4, primes())]); //[ 2, 3, 5, 7 ]


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var enterNumber = prompt("Enter number:");

for(var i=2; i<=enterNumber ;i++){

        var isPrime = true;

        for(var j=2; j<i; j++){
            if(i%j === 0 && i !== j){
                isPrime = false;
            }
        }
        if(isPrime === true){
            console.log(i);
        }
    }

您的原始代码有很多缺陷。要实现Eratosthenes筛,您需要将找到的每个素数添加到数组中,然后针对到目前为止找到的每个素数测试下一个候选素数。如果候选不能被数组中的任何素数整除,那么它就是素数,您可以将其添加到素数数组中。

这是一个工作版本(演示):

1
2
3
4
5
6
7
8
9
10
11
function start() {    
    var array = [2, 3];
    for (var i = 5; i <= 100; i += 2) {
        if (array.every(function(p) { return i % p; })) {
            array.push(i);
        }
    }
    var result = array.join(",");
    document.getElementById("output").innerHTML = result;
}
start();

请注意,这取决于ECMAScript 5中引入的Array.prototype.every


您有很多方法可以实现这一目标。

基本上您的方法是正确的,但是,您必须检查每个数字是否可以被到目前为止确定的每个素数整除:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var primes = [2],isPrime;

for (var i=3;i<100;i+=2){
    isPrime = true;
    // test the number you are examaning against
    // all the primes you found so far
    for (var j = 0;j<primes.length;j++){
        if (i%primes[j]==0){
            isPrime=false;
            break;
        }
    }
    if(isPrime){primes.push(i)}
}
console.log(primes);

在这里查看结果

或者,您可以使用Eratosthenes筛网对所有数字进行排序,以避免重复测试。

SoE的真正实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// initialize the array first
var numbers = [], primes = [], maxNumber = 100;

for(var i = 2;i<=maxNumber;i++){
 numbers.push(i);  
}

while(numbers.length){
    primes.push(numbers.shift());
    numbers = numbers.filter(
        function(i){return i%primes[primes.length-1]!=0}
    );
}

console.log(primes);

演示版


这可能是一种有效的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function calcPrimes(max){
    var primes = [];
    for(var i=2; i<=max; i++){
        var isPrime = true;
        for(var j=0; j<primes.length; j++){
            var p = primes[j];
            if( i % p === 0){
                //it is divisible by another prime, so it's not prime
                isPrime=false;
                break;
            }
            //you don't need to check primes bigger than sqrt(i)
            if(p*p > i)
                break;
         }
        if(isPrime)
            primes.push(i);
    }
    console.log(JSON.stringify(primes))
    console.log(primes.length)
}
calcPrimes(100);


这是一个工作示例,说明如何使用Eratosththenes筛子的变体生成无限数量的素数。这是一个真正的SoE,并且不会执行试验划分来确定数字是否为质数。它可能看起来有些奇怪,但这是因为它被设计为没有任何上限。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<input type=button value="Start" onClick="do_cancel(); do_once()">
<input type=button value="Stop" onClick="do_cancel()">
<table id="mytable"></table>


'use strict';
(function () {
    var ptable = document.getElementById("mytable");
    var prow = [2, 3];
    function insertPrimeIntoTable(prime) {
        prow.push(prime);
        if( prow.length < 10 ) return false;
        var tr = document.createElement('tr');
        for( var i = 0; i < prow.length; ++i ) {
            var cell = document.createElement('td');
            cell.appendChild( document.createTextNode( prow[i] ) );
            tr.appendChild( cell );
        }
        ptable.appendChild( tr );
        prow = [];
        return true;
    };

    var factors = [];
    function insertPrimeIntoSieve( factor ) {
        var where = factor;
        while( factors[where] )
            where += factor;
        /* while( factors.length < where ) factors.push(0); */
        factors[ where ] = factor;
    }

    var primes = [];
    var a_prime = 3, a_squared_prime = 9, maybe_prime = 3;
    var canceller;
    function do_once() {
        var factor = factors[0];
        maybe_prime += 2;
        if( factor ) {
            //if( 0 != (maybe_prime % factor) )
            //  throw"Unexpected remainder.";
            insertPrimeIntoSieve( factor );
        } else if( maybe_prime < a_squared_prime ) {
            insertPrimeIntoTable( maybe_prime );
            primes.push( maybe_prime );
        } else if( maybe_prime == a_squared_prime ) {
            insertPrimeIntoSieve( a_prime );
            a_prime = primes.shift();
            a_squared_prime = a_prime * a_prime;
        } else {
            throw"Critical math failure:  Programmer or compiler is innumerate.";
        }
        factors.shift();
        canceller = window.setTimeout( do_once, 5 );
    };
    function do_cancel() {
        if( canceller ) window.clearTimeout( canceller );
        canceller = null;
    }
    window.do_once = do_once;
    window.do_cancel = do_cancel;
})();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Please try this,
var a = [...Array(100).keys()];
var primeNumbers = a.map(v => {
    if (v % 2 === 0 || v % 3 === 0) {
      if (v === 2 || v === 3) {
       return v;
      } else {
       return;
      }
    } else {
      return v;
    }
});

primeNumbers.filter(val => val);

you will get 1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 25, 29, 31, 35, 37, 41, 43, 47, 49, 53, 55, 59, 61, 65, 67, 71, 73, 77, 79, 83, 85, 89, 91, 95, 97

最近正在使用质数,并已登陆此页面。这是我的使用Eratosthenes算法的Sieve和6k ± 1优化的解决方案,并且忽略了5的所有偶数和除数。

将代码复制并粘贴为html。打印大约10 seconds中的第一个1,000,000质数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
<!DOCTYPE html>
<HTML>
<HEAD>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.5/css/bulma.min.css">
<script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js">
<BODY>
<SCRIPT type="text/javascript">
// The largest integer Java natively supports is 2^53-1, so these
// routines are designed to work for *positive* integers up to that.

// Currently the function check does the idiot proof to see only positive
// integers (not too large) are passed to the other routines.

 
// trial_divide(N,max) uses trial division to seek the smallest
// prime divisor of N, returns 0 if none found.


function trial_divide(N,max) {
  // Trial divides the positive integer N by the primes from 2 to max
  // Returns the first prime divisor found, or 0 if none found
  // Note: if N < max^2 is a prime, then N will be returned.
  if (N%2 == 0) return 2;
  if (N%3 == 0) return 3;
  // No need to go past the square root of our number
  var Stop = Math.min(Math.sqrt(N),max);
  // Okay, lets"wheel factor" alternately adding 2 and 4
  var di=2;
  for(i=5; i<=Stop; i+=di, di=6-di) {
    if (N%i == 0) return i;
  };
  if (N >= max*max) return 0;
  return N;
}


// modmult(a,b,N) finds a*b (mod N) where a, b, and N can be
// up to (2^53-1)/2.  Might up this to 2^53-1 eventually...

  function modadd(a,b,N) {
  // When the integers a, b satisfy a+b > 2^53-1, then (a+b)%N is wrong
  // so we add this routine to allow us to reach a, b = 2^53-1.
    if (a+b > 9007199254740991) {
      // Could reduce a and b (mod N) here, but assuming that has already been done
      // won't hurt if not... subtract 2^52 from one, 2^52-1 from the other and the
      // add it back modulo N (MaxInt+1)  
      var t = ( (a-4503599627370496) + (b-4503599627370495) )%N;
      return ( t + (9007199254740991 % N) );
    }
    // Usual case: a + b is not too large:
    return ( (a+b)%N );
  }

function modmult(a,b,N) {
  if (a > N) a = a%N;
  if (b > N) b = b%N;
  if (a*b <= 9007199254740991) {
    return ((a*b)%N);
  } else {
    if (b > a) return modmult(b,a,N);

    // Right to left binary multiplication
    var t = 0;
    var f = a;
    while (b > 1) {
      if ((b & 1) == 1) t = modadd(t,f,N);
      b = Math.floor(b/2);
      f = modadd(f,f,N);
    };
    t = modadd(t,f,N);
    return t;
  }
}

// modpow(a,exp,N) finds a^exp (mod N) where a, b, and N are
// limited by modmult

function modpow(a,exp,N) {
  if (exp == 0) return 1;

  // Right to left binary exponentiation
  var t = 1;
  var f = a;
  while (exp > 1) {
    if ((exp & 1) == 1) {  // if exponent is odd
      t = modmult(t,f,N);
    }
    exp = Math.floor(exp/2);
    f = modmult(f,f,N);
  };
  t = modmult(t,f,N);
  return t;
}

// SPRP(N,a) checks if N (odd!) is a strong probable prime base a
// (returns true or false)

function SPRP(N,a) {
  var d = N-1; s = 1;           // Assumes N is odd!
  while ( ((d=d/2) & 1) == 0) s++;  // Using d>>1 changed the sign of d!
  // Now N-1 = d*2^s with d odd
  var b = modpow(a,d,N);
  if (b == 1) return true;
  if (b+1 == N) return true;
  while (s-- > 1) {
    b = modmult(b,b,N);
    if (b+1 == N) return true;
  }
  return false;
}

// The idiot proofing, answer returning script

function check(e){
  if (e.hasAttribute("disabled")) return;
  var start = performance.now();
  var TrialLimit = 1300; // Should be bigger, like 10000
  var N = document.getElementById("primenumbercheck").value;
  var Result ="Unknown error";
  var a;
   
  if (N > 9007199254740991) {
    Result ="Sorry, this routine will only handle integers below 9007199254740991.";
  } else if (N == 1) {
    Result ="The number 1 is neither prime or composite (it the multiplicative identity).";
  } else if (N < 1) {
    Result ="We usually restrict the terms prime and composite to positive integers";
  } else if (N != Math.floor(N)) {
    Result ="We usually restrict the terms prime and composite to positive integers";
  } else {
    // Okay, N is of a resonable size, lets trial divide
    window.status ="Trial dividing" + N +" to" + TrialLimit +".";
    i = trial_divide(N,TrialLimit);
    if (i > 0 && i != N) {
      Result = N+" is not a prime! It is"+i+" *"+N/i;
    } else if (N < TrialLimit*TrialLimit) {
      Result = N+" is a (proven) prime!";
    } else if ( SPRP(N,a=2) && SPRP(N,a=3) && SPRP(N,a=5) && SPRP(N,a=7)
            && SPRP(N,a=11) && SPRP(N,a=13) && SPRP(N,a=17)) {
      // Some of these tests are unnecessary for small numbers, but for
      // small numbers they are quick anyway.
      if (N < 341550071728321) {
        Result = N +" is a (proven) prime.";
      } else if (N == 341550071728321) {
        Result = N+" is not a prime! It is 10670053 * 32010157.";
      } else {
        Result = N +" is probably a prime (it is a sprp bases 2, 3, 5, 7, 11, 13 and  17).";
      };
    } else {
      Result = N+" is (proven) composite (failed sprp test base"+a+").";
    };
  };
  var end = performance.now();
  var timeTaken = end - start;
  window.status="Done!"; // here so says done when present alert box
  var x = document.getElementsByClassName("primecheck");
  x[0].innerHTML = Result;
  setTimer(timeTaken);

}

function generate(e){
  if (e.hasAttribute("disabled")) return;
  var start = performance.now();
  var x = document.getElementsByClassName("primelist");
  var N = document.getElementById("primenumberlist").value;

  var i = 2;
  var Result ="2,";
  var currentInt = 3;
  var possiblePrime;
  if (N == 2)
    Result = Result + currentInt +",";
  else {
    while (i < N) {
      possiblePrime = false;
        if(currentInt == 3) {
          Result = Result + currentInt +",";
            possiblePrime = false;
        }
    else if(currentInt % 5 == 0 && currentInt > 5) {
      possiblePrime = false;
    }
        else if(currentInt % 6 == 1 || currentInt % 6 == 5)
          possiblePrime = true;
        if(possiblePrime) {
          if(trial_divide(currentInt,Math.ceil(Math.sqrt(currentInt))) == currentInt) {
            Result = Result + currentInt +",";
            i++;
          }
        }
        currentInt = currentInt + 2;
      }
    }
  var end = performance.now();
  var timeTaken = end - start;
  x[0].innerHTML = Result.substring(0, Result.length - 2);
  setTimer(timeTaken);
}

function setTimer(timeTaken) {
  var timerElement = document.getElementsByClassName("timeElapsed")[0];
  var timerPreText ="Time Elapsed:";
  var duration = convertMS(timeTaken);
  timerPreText = timerPreText + duration.day +" days:" + duration.hour +" hours:" + duration.minute +" minutes:" + duration.seconds +" seconds" +":" +

duration.milliseconds +" milliseconds";
  timerElement.innerHTML = timerPreText;
}

function isNumberKey(evt)
{
  var charCode = (evt.which) ? evt.which : event.keyCode
  if (charCode > 31 && (charCode < 48 || charCode > 57))
     return false;
     return true;
}

function convertMS( milliseconds ) {
    var day, hour, minute, seconds, milliseconds;
    seconds = Math.floor(milliseconds / 1000);
    milliseconds = milliseconds - (seconds * 1000);
    milliseconds = milliseconds.toFixed(2);
    minute = Math.floor(seconds / 60);
    seconds = seconds % 60;
    hour = Math.floor(minute / 60);
    minute = minute % 60;
    day = Math.floor(hour / 24);
    hour = hour % 24;
    return {
        day: day,
        hour: hour,
        minute: minute,
        seconds: seconds,
    milliseconds: milliseconds
    };
}

function checkInput(input, buttonId)
{
    var name = input.value;
    var cansubmit = (name.length > 0);
    if (cansubmit) {
        document.getElementById(buttonId).removeAttribute("disabled");
    } else {
        document.getElementById(buttonId).setAttribute("disabled", null);
    }
};




 
    <p class="timeElapsed">Time elapsed will be shown here!
</p>
 
</article>


 
    Check prime number
   
    <input id="primenumbercheck" class="input is-rounded" type="text" placeholder="Enter the number you wanna check..." style="max-width: 25%;"

onkeypress="return isNumberKey(event)" onkeyup="checkInput(this, 'primenumbercheckButton')">
    Check
   
 
</article>


 
    Prime check goes here!
 



 
    List prime numbers
   
    <input id="primenumberlist" class="input is-rounded" type="text" placeholder="Enter the number of prime numbers you wanna generate..." style="max-width:

35%;"
onkeypress="return isNumberKey(event)" onkeyup="checkInput(this, 'primenumberlistButton')">
    List
   
 
</article>


 
    Prime list goes here!
 




</BODY>
</HEAD>
</HTML>


我知道在2014年会问这个问题,但是如果万一OP或任何人想知道如何使用Javascript生成小素数,我已经在https://github.com/HMaxF/generate-small-prime中共享了小JS代码-数。

在我的Macbook Pro中,我可以在25秒左右的时间内生成2到1亿之间的所有质数,但是您的计算机结果会有所不同。


我同意p.s.w.g.您的原始代码有很多缺陷。

1
2
3
4
5
6
7
8
var prime = [2,3,5,7];

for(var x = 0; x < 100; x++){
    var isPrime = prime.map(n => x%n > 0).filter(t => !t).length <= 0;
    if(isPrime || prime.includes(x)){
        console.log(x);
   }
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function printPrimes(num) {
    let sum = []
  for(let i = 2; i<=num; i++) {
        if(check(i)) {
            sum.push(i)
        }
    }
    return sum
}
function check(num) {     // function to check number is prime or not
    if(num <= 1 || typeof num !== 'number') {
        return false
    }else if(num ===2) {
        return true
    }else if (num%2 === 0) {
        return false
    }
    for(let i=3; i*i <= num;i +=2) {
        if(num%i === 0) {
            return false
        }
    }
   return true
}  
console.log(printPrimes(100))


只需将此Java脚本用于从2到所需数字的质数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function primeFactorsTo(num)
{
    var store  = [], i, j, primes = [];
    for (i = 2; i <= num; ++i)
    {
        if (!store [i])
          {
            primes.push(i);
            for (j = i << 1; j <= num; j += i)
            {
                store[j] = true;
            }
        }
    }
    return primes;
}

console.log(primeFactorsTo(200));

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
I’ve Made the easiest Algorithm to solve this Problem

Step 1 –  Create a function to check a number is prime or not  (PrimeFilter) .

Step 2 – Create another function to print prime numbers smaller than given  number ,
               inside it declare an empty array .
Step 3 – Loop from 2 ( first prime number ) to the given number , and pass every loop value
              to the function PrimeFilter ( It will check every loop value if its prime or not ) .
Step 4 – If its a prime add it to the empty array .   Thats it :)


    function PrimeFilter(num){
         if(num===0){
           return false;
        }
        else if(num===1){
            return false;
        }

        else if(num===2){
            return true;
        }

        else {

            for(var i=2; i<num; i++){
                if(num%i===0){
                    return false;
                }
            }
            return true;
         }
     }

     function UptoPrime(number){
        var List =[];
         for(var i=2; i<=number; i++){
            if(PrimeFilter(i)){
                List.push(i);
            }
         }
         console.log(List.join(' '));
    }

参照此答案,这将检查质数并在给定范围之间打印所需的质数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const isPrime = num => {
  for(let i = 2; i < num; i++)
    if(num % i === 0) return false;
  return num > 1;
}

primes = [] ;

for(let i = 2; i < max ; i ++) {
if(isPrime(i)) {
   primes.push(i)
 }
}

console.log(primes);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function isPrime(num) {
    if (num % 2 == 0) {
        return false;
    }

    let n = Math.sqrt(num);

    for ( var i = 3; i <= n; i += 2 ) {
        if ( num % i === 0 ) {
            return false;
        }
    }

    return true;
}

function print(n) {
    var arr = [2];
    for ( var i = 3; i < n; i+=2 ) {
        if ( isPrime(i) ) {
            arr.push(i);
        }
    }
    console.log(arr);
}

print(100);