The validation of prime numbers may be the subject of so-called "cycle exercises". Because the algorithm is too simple (it is not known whether the direct violence cycle can be an algorithm). The classic method is to try to remove, with the loop variable i from 2 to n-1, if there is a modulus of 0, it will return to false directly. In the end, no 0 has been modeled, return true. This algorithm can also optimize n-1 to sqrt (n). The principle is: set X to a number greater than sqrt (n), n=xy, then y must be less than sqrt (n), so as long as the validation to sqrt (n), you can verify to Y, equivalent to the validation of X.
The above-mentioned brute force algorithm, if there are N number to verify, then the time complexity of O (sqrt (N) *n), in the face of similar to the n=100000000 data is obviously powerless. Therefore, we can use the filter method: In turn, the number of 2, 3, 5, 7 and so on the number of primes, and finally can be obtained a prime table. After the table is built, the query prime number is as long as O (1) time complexity. But for the above orders of magnitude N, still can not quickly find a prime table, consumption time of up to 2.1s. So, we have to optimize it.
As is known to all, except 2, all the even numbers are composite. Therefore, an even number can be removed from the Prime number table. That is, Prime[0] stands for 3 is the prime number, Prime[1] represents 5 ... Also, the sieve number does not have to sift to N, as long as the sieve to sqrt (n) can be. Set Key1 (i) =i*2+3;key2 (i) = (i-3)/2, which corresponds to the position of the odd and odd I in the Prime number table, respectively, corresponding to the first position in the Prime number table. The original sieve, i* (2,3,4 ...) Simplify for i* (3,5,7 ...). The number of first-time sieves is Key2 (Key1 (i*i)), simplified (i*i) *8+3, followed by Key2 (Key1 (i+2))-key2 (Key1 (i)), and i*2+3 after simplification, so the program is easy to write after the deduction is complete. The source code is given below:
#include <cstring>#include<cmath>#include<cstdio>using namespacestd;Const intn=100000001;Const intN1= (n3)/2;BOOLprime[n1+1];inttmp;intMainvoid) {memset (prime,true,sizeof(prime)); for(intI=0;i< (int(sqrt (N))-3) >>1;++i) { if(Prime[i]) {tmp= ((i*i) <<3)+3; while(tmp<N1) {Prime[tmp]=false; TMP+ = (i<<1)+3; }}} printf ("%d\t",2); for(intI=0; i<n1;++i)if(Prime[i]) printf ("%d\t", i*2+3); return 0;}
Attach the time and memory consumption statistics of various methods (test environment: Mingw4.9.2,intel Xeon E3 1230v2, remove IO output time):
|
Time |
Memory |
Violent Trial Division |
N/A (too long) |
1Mb |
Simple Screening Method |
2.1s |
98Mb |
Optimized Screening method |
1.0s |
50Mb |
Prime number verification algorithm--facing big data