Most efficient code for the first 10000 prime numbers?

前端 未结 30 1421
日久生厌
日久生厌 2020-11-29 19:09

I want to print the first 10000 prime numbers. Can anyone give me the most efficient code for this? Clarifications:

  1. It does not matter if your code is ineffici
30条回答
  •  旧巷少年郎
    2020-11-29 19:32

    Here is my code which finds first 10,000 primes in 0.049655 sec on my laptop, first 1,000,000 primes in under 6 seconds and first 2,000,000 in 15 seconds
    A little explanation. This method uses 2 techniques to find prime number

    1. first of all any non-prime number is a composite of multiples of prime numbers so this code test by dividing the test number by smaller prime numbers instead of any number, this decreases calculation by atleast 10 times for a 4 digit number and even more for a bigger number
    2. secondly besides dividing by prime, it only divides by prime numbers that are smaller or equal to the root of the number being tested further reducing the calculations greatly, this works because any number that is greater than root of the number will have a counterpart number that has to be smaller than root of the number but since we have tested all numbers smaller than the root already, Therefore we don't need to bother with number greater than the root of the number being tested.

    Sample output for first 10,000 prime number
    https://drive.google.com/open?id=0B2QYXBiLI-lZMUpCNFhZeUphck0 https://drive.google.com/open?id=0B2QYXBiLI-lZbmRtTkZETnp6Ykk

    Here is the code in C language, Enter 1 and then 10,000 to print out the first 10,000 primes.
    Edit: I forgot this contains math library ,if you are on windows or visual studio than that should be fine but on linux you must compile the code using -lm argument or the code may not work
    Example: gcc -Wall -o "%e" "%f" -lm

    #include 
    #include 
    #include 
    #include 
    
    /* Finding prime numbers */
    int main()
    {   
        //pre-phase
        char d,w;
        int l,o;
        printf("  1. Find first n number of prime numbers or Find all prime numbers smaller than n ?\n"); // this question helps in setting the limits on m or n value i.e l or o 
        printf("     Enter 1 or 2 to get anwser of first or second question\n");
        // decision making
        do
        {
            printf("  -->");
            scanf("%c",&d);
            while ((w=getchar()) != '\n' && w != EOF);
            if ( d == '1')
            {
                printf("\n  2. Enter the target no. of primes you will like to find from 3 to 2,000,000 range\n  -->");
                scanf("%10d",&l);
                o=INT_MAX;
                printf("  Here we go!\n\n");
                break;
            }
            else if ( d == '2' )
            {
                printf("\n  2.Enter the limit under which to find prime numbers from 5 to 2,000,000 range\n  -->");
                scanf("%10d",&o);
                l=o/log(o)*1.25;
                printf("  Here we go!\n\n");
                break;
            }
            else printf("\n  Try again\n");
        }while ( d != '1' || d != '2' );
    
        clock_t start, end;
        double cpu_time_used;
        start = clock(); /* starting the clock for time keeping */
    
        // main program starts here
        int i,j,c,m,n; /* i ,j , c and m are all prime array 'p' variables and n is the number that is being tested */
        int s,x;
    
        int p[ l ]; /* p is the array for storing prime numbers and l sets the array size, l was initialized in pre-phase */
        p[1]=2;
        p[2]=3;
        p[3]=5;
        printf("%10dst:%10d\n%10dnd:%10d\n%10drd:%10d\n",1,p[1],2,p[2],3,p[3]); // first three prime are set
        for ( i=4;i<=l;++i ) /* this loop sets all the prime numbers greater than 5 in the p array to 0 */
            p[i]=0;
    
        n=6; /* prime number testing begins with number 6 but this can lowered if you wish but you must remember to update other variables too */
        s=sqrt(n); /* 's' does two things it stores the root value so that program does not have to calaculate it again and again and also it stores it in integer form instead of float*/
        x=2; /* 'x' is the biggest prime number that is smaller or equal to root of the number 'n' being tested */
    
        /* j ,x and c are related in this way, p[j] <= prime number x <= p[c] */
    
        // the main loop begins here
        for ( m=4,j=1,c=2; m<=l && n <= o;)
        /* this condition checks if all the first 'l' numbers of primes are found or n does not exceed the set limit o */
        {
                // this will divide n by prime number in p[j] and tries to rule out non-primes
                if ( n%p[j]==0 )
                {
                    /* these steps execute if the number n is found to be non-prime */
    
                    ++n; /* this increases n by 1 and therefore sets the next number 'n' to be tested */
                    s=sqrt(n); /* this calaulates and stores in 's' the new root of number 'n' */
                    if ( p[c] <= s && p[c] != x ) /* 'The Magic Setting' tests the next prime number candidate p[c] and if passed it updates the prime number x */
                    {
                        x=p[c];
                        ++c;
                    }
                    j=1;
                    /* these steps sets the next number n to be tested and finds the next prime number x if possible for the new number 'n' and also resets j to 1 for the new cycle */
                    continue; /* and this restarts the loop for the new cycle */
                }
                // confirmation test for the prime number candidate n
                else if ( n%p[j]!=0 && p[j]==x )
                {
                    /* these steps execute if the number is found to be prime */
                    p[m]=n;
                    printf("%10dth:%10d\n",m,p[m]);
                    ++n;
                    s = sqrt(n);
                    ++m;
                    j=1;
                    /* these steps stores and prints the new prime number and moves the 'm' counter up and also sets the next number n to be tested and also resets j to 1 for the new cycle */
                    continue; /* and this restarts the loop */
                    /* the next number which will be a even and non-prime will trigger the magic setting in the next cycle and therfore we do not have to add another magic setting here*/
                }
                ++j; /* increases p[j] to next prime number in the array for the next cycle testing of the number 'n' */
                // if the cycle reaches this point that means the number 'n' was neither divisible by p[j] nor was it a prime number
                // and therfore it will test the same number 'n' again in the next cycle with a bigger prime number
        }
        // the loops ends
        printf("  All done !!\n");
        end = clock();
        cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
        printf("  Time taken : %lf sec\n",cpu_time_used);
    }
    

提交回复
热议问题