To find all primes in n

Source: Internet
Author: User
1. Prime number a nd related
Prime, also known as Prime, in a natural number greater than 1, except 1 and this integer itself, can not be divisible by other natural numbers.    A number larger than 1, but not prime, is called composite.    1 and 0 are neither primes nor composite. The basic theorem of arithmetic proves that each positive integer greater than 1 can be written as the product of a prime number, and the form of this product is unique.
2, Trial Division to find prime numbers
Algorithm Description: According to the definition of prime number, we can not be divided into 1 and the integers of the integer is prime. So, we can tell whether a prime is a prime number, just see if it can be 2~sqrt (i) between the numbers of integers. And all the primes in n is a cyclic repetition of the above process.


The C language implementation is shown below.





#include <stdio.h>
#include <time.h>
#include <math.h>
#include <malloc.h>
//Trial Division
#define NUM 10000

int test_prime (int n)
{
    int count = 0;
    int I, J;
    int *num = (int *) malloc (sizeof (int) * n);
    num[count++] = 2;
     
    for (i = 3; l <= N; i++)
    {for
        (j = 2; J <= sqrt (i); + j)
        {
            if (i% j = 0)
            {
                break;}
        }
        if (J > sqrt (i))
        {
            num[count++] = i;
        }
    }
    Free (num);
    return count;
}
int main ()
{
    int count;
    clock_t Start,end;
    start = Clock ();
    Count = Test_prime (NUM);
    end = Clock ();
    printf ("Number of primes in%d:%d, total time elapsed:%d milliseconds \ n", NUM, Count, End-start);

    return 0;
}

when the data is very large, the time consumption increases relatively fast.

3, Trial Division optimization scheme  

       Careful study of trial division, you can find the following problems:  

  1> in the cyclic condition repeated call sqrt (i), which is obviously a waste of time;   

2> Judging primes, really need to take 2-sqrt (i) between all the integers removed. We know that composite can be decomposed into several prime numbers, so as long as the prime numbers between 2-sqrt (i) cannot be divisible by I, the    c language implementation is as follows.

// Find all prime numbers in N
#include <stdio.h>
#include <time.h>
#include <math.h>
#include <malloc.h>
// try division
#define NUM 1000000

int Test_prime (int n)
{
    int count = 0;
    int i, j, k, stop;
    // Allocate space
    int * num = (int *) malloc (sizeof (int) * n);
    // 2 must be a prime number
    num [count ++] = 2;
    stop = 0;
    for (i = 3; i <= n; i ++)
    {
        // It is inefficient to repeatedly call sqrt in a loop, so k is introduced
        k = (int) sqrt (i);
        // Stop is used to count the number of prime numbers less than the current k value
        while (num [stop] <= k && stop <count)
        {
            stop ++;
        }
        for (j = 0; j <stop; j ++)
        {
            if (i% num [j] == 0)
            {
                // i cannot be divisible by primes between 2-sqrt (i)
                break;
            }
        }
        if (j == stop)
        {
            num [count ++] = i;
        }
        
    }
    free (num);
    return count;
}
int main ()
{
    int count;
    clock_t start, end;
    start = clock ();
    count = Test_prime (NUM);
    end = clock ();
    printf ("The prime numbers in% d are:% d, the total time is:% d milliseconds \ n", NUM, count, end-start);
    
    return 0;
}
Compared to the algorithm before optimization, TIME provides a lot. In particular, the amplitude of the time growth curve becomes smaller, and the greater the N value, the optimized algorithm is more efficient than the optimized algorithm.
4, composite filtration screening method
Algorithm Description: By the definition of prime numbers, the prime number n cannot be divisible by any integer between N-1, and conversely, as long as N, which can be divisible by any integer between N-1, is not a prime number.    Therefore, we use the exclusion method: is the number of all numbers within N, as long as one by one to remove the value of a multiple of N-1, the rest is prime. The C language implementation is shown below.
Merge filter
#include <stdio.h>
#include <time.h>
#include <math.h>
#include < Malloc.h>
//Trial Division
#define NUM 10000

int test_prime (int n)
{
    int count = 0;
    int I, J;
    Allocate space, the reason is n+1, because a waste of a num[0]
    char *num = (char *) malloc (sizeof (char) * (n + 1));

    Initialize prime number tag for
    (i = 2; i<= n; i++)
    {
        num[i] = 1;
    }
    The filter composite for
    (i = 2; I <= n-1; i++)
    {for
        (j = 2; J * I <= N; j + +)
        {
            //i*j is multiplied by two integers by N-1. Obviously not prime
            num[i*j] = 0;
        }
    }
    Number of statisticians for
    (i = 2; i<= n; i++)
    {
        if (1 = = Num[i])
        {
            count++;
        }
    }
    Free (num);
    return count;
}
int main ()
{
    int count;
    clock_t Start,end;
    start = Clock ();
    Count = Test_prime (NUM);
    end = Clock ();
    printf ("Number of primes in%d:%d, total time elapsed:%d milliseconds \ n", NUM, Count, End-start);
    
    return 0;
}

Many of the above procedures have adopted a relatively inefficient approach, in order to compare with the optimization of the later, this is the same as I do beginners commonly used version, therefore, to learn to optimize.
5, Combined Screening method optimization scheme

The problem with the above algorithm is:

 1> in the outer layer of the loop, it needs to be carried out to n-1. No, because the number between n/2-(n-1) is obviously not divisible by N,

 2> in the inner loop is obviously inefficient, considering that the addition and subtraction of the computer is faster than multiplication, it is possible to consider variable multiplication as additive; 

3> in the process of changing the flag in the loop, In fact, a very large number of repeated calculations, such as 6 = 2*3 = 3*2, is repeated zero, so can be avoided; C language implementation is as follows.

// Optimization scheme of combined screening method
#include <stdio.h>
#include <time.h>
#include <math.h>
#include <malloc.h>

#define NUM 300000

int Test_prime (int n)
{
    int count = 0;
    int i, j;
    // Allocate space
    char * num = (char *) malloc (sizeof (char) * (n + 1));
    
    // Initialize prime numbers
    num [2] = 1;
    // Note that here is i <n, i <= n in the above example
    for (i = 3; i <n; i ++)
    {
        num [i ++] = 1;
        num [i] = 0; // Even numbers are naturally not prime numbers
    }
    // If n is odd
    if (n% 2! = 0)
    {
        num [n] = 1;
    }
    // Filter from 3, because multiples of 2 are removed during initialization
    for (i = 3; i <= n / 2; i ++)
    {
        if (0 == num [i])
        {
            continue;
        }
        // Filter from 2 times i
        for (j = i + i; j <= n; j + = i)
        {
            num [j] = 0;
        }
    }
    // Count the number of primes
    for (i = 2; i <= n; i ++)
    {
        if (1 == num [i])
        {
            count ++;
        }
    }
    free (num);
    return count;
}
int main ()
{
    int count;
    clock_t start, end;
    start = clock ();
    count = Test_prime (NUM);
    end = clock ();
    printf ("The prime numbers in% d are:% d, the total time is:% d milliseconds \ n", NUM, count, end-start);
    
    return 0;
}

 Really much faster than before, optimization really can bring time to improve, so I am very happy. Later I thought about adding a supplement: If I optimize the red part of the code above, as shown below.
Filter starting from 3, because, a multiple of 2 in the initialization is removed for the for
    (i = 3; I <= n/2; i = i + 2)
    {
        //In this case, you already have a function that rejects even
        if (0 = = Num[i]){
            continue;
        }
        Starting from I twice Times filter
        for (j = i + i; J <= n;j+=i)
        {
            //is directly assigned to the value fast. Or is it here to add judgment fast? I don't know. Solving..
            if (j% 2 = = 0)
            {
                continue;
            }
            else
            {
                Num[j] = 0;}}
    }

The first part of the red, I will be the original odd and even to judge, changed to only the odd number of judgments, the second part of the red, I will be odd multiples of the direct culling of an even number, to the odd multiples of the assignment; The test for num = 300000 .
The time is only 7 milliseconds, and the time is faster than num = 300000 before optimization.







// Optimization scheme of combined screening method
#include <stdio.h>
#include <time.h>
#include <math.h>
#include <malloc.h>
#include <string.h>
#define NUM 10000

int Test_prime (int n)
{
    int i, j;
    // Prime number statistics
    int count = 0;
    // Allocate space for prime numbers, understand why +1, because a num [0] is wasted
    char * num = (char *) malloc (n + 1);
    // Why use it, please study the following carefully
    int mpLen = 2 * 3 * 5 * 7 * 11 * 13;
    char magicPattern [2 * 3 * 5 * 7 * 11 * 13];
    // Strange code, think.
    for (i = 0; i <mpLen; i ++)
    {
        magicPattern [i ++] = 1;
        magicPattern [i ++] = 0;
        magicPattern [i ++] = 0;
        magicPattern [i ++] = 0;
        magicPattern [i ++] = 1;
        magicPattern [i] = 0;
    }
    for (i = 4; i <= mpLen; i + = 5)
    {
        magicPattern [i] = 0;
    }
    for (i = 6; i <= mpLen; i + = 7)
    {
        magicPattern [i] = 0;
    }
    for (i = 10; i <= mpLen; i + = 11)
    {
        magicPattern [i] = 0;
    }
    for (i = 12; i <= mpLen; i + = 13)
    {
        magicPattern [i] = 0;
    }
    
    // new initialization method, kill all multiples of 2, 3, 5, 7, 11, 13
    // And use memcpy to batch process mpLen magicPattern
    int remainder = n% mpLen;
    char * p = num + 1;
    char * pstop = p + n-remainder;
    while (p <pstop)
    {
        memcpy (p, magicPattern, mpLen);
        p + = mpLen;
    }
    if (remainder> 0)
    {
        memcpy (p, magicPattern, remainder);
    }
    num [2] = 1;
    num [3] = 1;
    num [5] = 1;
    num [7] = 1;
    num [11] = 1;
    num [13] = 1;
    
    // Filter from 17 because multiples of 2,3,5,7,11,13 have been removed
    // to n / 13
    int stop = n / 13;
    for (i = 17; i <= stop; i ++)
    {
        // i is composite
        if (0 == num [i])
        {
            continue;
        }
        
        // Filter from 17 times of i
        int step = i * 2;
        for (j = i * 17; j <= n; j + = step)
        {
            num [j] = 0;
        }
    }
    
    // Count the number of primes
    for (i = 2; i <= n; i ++)
    {
        if (num [i])
        {
            count ++;
        }
    }
    
    // release memory
    free (num);
    
    return count;
}
int main ()
{
    int count;
    clock_t start, end;
    start = clock ();
    count = Test_prime (NUM);
    end = clock ();
    printf ("The prime numbers in% d are:% d, the total time is:% d milliseconds \ n", NUM, count, end-start);
    
    return 0;
}

To tell the truth, this kind of thought is really great, now I can not think of, thank the author, let me have a broader insight.
7. Other
In addition to the above several algorithms, such as the Rabin Miller Prime test algorithm, it is difficult to feel this algorithm, first take a good look, and so understand, and then make up.

Through today's tangled, for the prime number has a more profound understanding and understanding, feel that they are much worse, need more efforts. In addition, thanks to the author of Baidu Space Doforfun_net, gave me a great inspiration, learned a lot.













Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.