Some method of determining primes summary (including C ++ code)
A prime number is defined
Prime (prime number), also known as a prime number , the number 1 only refers to its own nature and in number factor greater than 1. For example, a prime number is 2, 1 and 2 which is only a factor of two; 29 is a prime number, which is only a factor of two and 29; 51 is not a prime number, in addition to 1 and 51, 3 and 17, it has a factor of two, so that 51 is a composite number .
Second, the prime method for determining
Given a positive integer n (n≥2):
Method 1. Definitions
Divided by n is about [2, n-1] of all integers, if a remainder after which the operand is 0, that the number is a factor of n, so that n is not a prime number. code show as below:
bool isPrime(int n){
bool yes=true;
for(int i=2;i<n;i++){
if(n%i==0){
yes=false;
break;
}
}
return yes;
}
2. Define Method to Improve
Since the factor n always appear in pairs, and are distributed in [1, ]with[ , The n] range (number Ruoyin We as two repeat factor), then we only need to determine a range. code show as below:
bool isPrime2(int n){
bool yes=true;
for(int i=2;i<=sqrt(n);i++){
if(n%i==0){
yes=false;
break;
}
}
return yes;
}
3. Method modulo
When n≥6, since n can be expressed as 6x + 1,6x + 2,6x + 3,6x + 4,6x + 5,6x (x≥1) a medium, then, if the expression for n 6x + 2,6x + 4 or 6x, it is clear that n is not a prime number; therefore, when n is 6x + 1 expression or 6x + 5, it may prime number, then the application method. code show as below:
bool isPrime3(int n){
bool yes=false;
if(n==2||n==3||n==5){ //当n<6时列举即可
yes=true;
}
else if(n%6==1||n%6==5){ //通过判断余数的方式来判断n的表达式
yes=true;
for(int i=2;i<=sqrt(n);i++){
if(n%i==0){
yes=false;
break;
}
}
}
return yes;
}
Test, time consuming
### 4.筛选法(Eratosthenes筛选)
我们可以很容易的判断出2、3、5等较简单的数是素数,而且,当一个数是素数后,它的倍数一定为合数。因此,我们可以将一定范围的整数筛选掉合数,剩下的即是素数。代码如下:
```cpp
bool isPrime4(int n){
bool yes=false;
//先生成一定范围的整数表,再应用筛选法,得到素数表,最后与素数表比对
//生成0~100000内的素数表
int num[100000]={0}; //0表示素数,1表示合数
for(int i=2;i<100000;i++){
if(!num[i]){
for(int j=i+i;j<100000;j+=i){
num[j]=1;
}
}
}
if(!num[n]){
yes=true;
}
return yes;
}
5. Improved screening
First of all, we can be sure that all primes except 2 are odd, it is possible to establish a means greater than the odd array 2, so that both expanded the judgment, but also reduce the number of judges; and then, we get the odd array of 3, 5, 7,9 ...... to 3 as an example, according to the method we should be screened out 4 3 × 2,3 × 3,3 × 4 ...... but where the 3 × 2,3 × 4 ...... is an even number, has been screened out, and Thus only starts from 3 × 3, screen out 3 × 3,3 × 5,3 × 7 ...... when screening a multiple of 5, the same should start with 5 × 2, but 5 × 2,5 × 4 ...... is even, then you should consider starting from 5 × 3, 5 × 3 but already sieve at screening out a multiple of 3, so screening should be a multiple of 5 from 5 × 5 began, screened out 5 × 7,5 × 9 ...... when we observe the number of filter groups, there is such a rule: if a prime number, then the filter starts from a × a, screen out a × a + 2 × a × i (i = 0,1, 2……).
A × a reason from the start screen: 4 by methods we should be screened out a × 2, a × 3, a × 4 ...... wherein a × 2, a × 4 ...... is an even number, has been screened out, and when from a when the start × 3 filter, if a> 3, to be sure, when screening multiple of 3 has been screened out in this 3 × a number, then the filter starts a × 5, the same token, if a> 5, then the filter 5 when multiples have been screened out this number of 5 × a; so until the beginning screening a × a, and it did not process before being screened out.
Why screen out a × a + 2 × a × i (i = 0,1,2 ......)? We can look at the conversion equation: a × a + 2 × a × i = a × (a + 2 × i). Screening can be seen that when starting from a × a, screen out a × (a + 0), a × (a + 2), a × (a + 4) ...... line with the law in the previous procedure.
The above process is summarized as Code:
bool isPrime5(int n){
bool yes=false;
int num[100000]={0}; //生成3~2*99999+3范围内的奇数数组
//先判断当n=2时的情况
if(n==2){
yes=true;
}
else{
for(int i=0;i<100000;i++){
if(!num[i]){
for(int j=(2*i+3)*(2*i+3);j<(2*100000+3);j+=2*(2*i+3)){
num[(j-3)/2]=1;
}
}
}
}
if((n-3)%2==0){
if(!num[(n-3)/2]){
yes=true;
}
}
return yes;
}
Third, the summary
The above-mentioned methods are put together, as follows:
#include <iostream>
#include <math.h>
#include <time.h>
#define SIZE 10000
using namespace std;
bool isPrime(int n) {
bool yes = true;
for (int i = 2; i < n; i++) {
if (n % i == 0) {
yes = false;
break;
}
}
return yes;
}
bool isPrime2(int n) {
bool yes = true;
for (int i = 2; i <= sqrt(n); i++) {
if (n % i == 0) {
yes = false;
break;
}
}
return yes;
}
bool isPrime3(int n) {
bool yes = false;
if (n == 2 || n == 3 || n == 5) {
yes = true;
}
else if(n%6==1||n%6==5) {
yes = true;
for (int i = 2; i <= sqrt(n); i++) {
if (n % i == 0) {
yes = false;
break;
}
}
}
return yes;
}
bool isPrime4(int n) {
bool yes = false;
int num[SIZE] = { 0 };
for (int i = 2; i < SIZE; i++) {
if (!num[i]) {
for (int j = i + i; j < SIZE; j += i) {
num[j] = 1;
}
}
}
if (!num[n]) {
yes = true;
}
return yes;
}
bool isPrime5(int n) {
bool yes = false;
int num[SIZE] = { 0 };
if (n == 2) {
yes = true;
}
else {
for (int i = 0; i < SIZE; i++) {
if (!num[i]) {
for (int j = (2 * i + 3) * (2 * i + 3); j < (2 * SIZE + 3); j += 2 * (2 * i + 3)) {
num[(j - 3) / 2] = 1;
}
}
}
}
if ((n - 3) % 2 == 0) {
if (!num[(n - 3) / 2]) {
yes = true;
}
}
return yes;
}
int main() {
cout << "function isPrime():" << endl;
time_t before = clock();
for (int i = 2, j = 0; i < 10000; i++) {
if (isPrime(i)) {
cout << i << " ";
j++;
}
if (j == 9) {
cout << endl;
j = 0;
}
}
time_t after = clock();
cout << endl;
cout << static_cast<double>((after - before) * 1000 / CLOCKS_PER_SEC) << "(ms)" << endl;
cout << "function isPrime2():" << endl;
before = clock();
for (int i = 2, j = 0; i < 10000; i++) {
if (isPrime2(i)) {
cout << i << " ";
j++;
}
if (j == 9) {
cout << endl;
j = 0;
}
}
after = clock();
cout << endl;
cout << static_cast<double>((after - before) * 1000 / CLOCKS_PER_SEC) << "(ms)" << endl;
cout << "function isPrime3():" << endl;
before = clock();
for (int i = 2, j = 0; i < 10000; i++) {
if (isPrime3(i)) {
cout << i << " ";
j++;
}
if (j == 9) {
cout << endl;
j = 0;
}
}
after = clock();
cout << endl;
cout << static_cast<double>((after - before) * 1000 / CLOCKS_PER_SEC) << "(ms)" << endl;
cout << "function isPrime4():" << endl;
before = clock();
for (int i = 2, j = 0; i < 10000; i++) {
if (isPrime4(i)) {
cout << i << " ";
j++;
}
if (j == 9) {
cout << endl;
j = 0;
}
}
after = clock();
cout << endl;
cout << static_cast<double>((after - before) * 1000 / CLOCKS_PER_SEC) << "(ms)" << endl;
cout << "function isPrime5():" << endl;
before = clock();
for (int i = 2, j = 0; i < 10000; i++) {
if (isPrime5(i)) {
cout << i << " ";
j++;
}
if (j == 9) {
cout << endl;
j = 0;
}
}
after = clock();
cout << endl;
cout << static_cast<double>((after - before) * 1000 / CLOCKS_PER_SEC) << "(ms)" << endl;
return 0;
}
We Run the code (operating environment: vs2019, debug, x64), time-consuming results are as follows:
the isPrime (): 379ms
isPrime2 (): 370ms
isPrime3 (): 400ms
isPrime4 (): 1008ms
isPrime5 (): 1028ms
discovery efficiency of the process 2 highest. I may be the code to be optimized, the efficiency of the method 3 is not high. Method 4 and 5 and the method of Mr. table needs to be a prime number, and then to compare, the time consumed will increase. If the table is to generate a prime number, an integer is determined whether or not a prime number, the efficiency of the two methods may be relatively high. Wherein the method of generating a larger prime number table range.