Optimizing prime numbers code?

后端 未结 9 1757
别那么骄傲
别那么骄傲 2021-01-25 01:53

I wrote this code to show the primes between 1 and 100. The only condition is to do not use functions, whole code should be inline. I would ask if I can improve (optimize) it mu

相关标签:
9条回答
  • 2021-01-25 02:17

    Depends which optimisation you're looking to do. Yours is as good as possible that I can see if you're optimising for space first, time second (well, close - as long as you listen to @Paul, it will be). If you reverse the priorities, the Sieve of Erastothenes is faster (but will take up 100 booleans of your memory).

    0 讨论(0)
  • 2021-01-25 02:17

    Two simple optimizations you could do:

    cout << 2 << '\t';
    for (int i = 3; i <= 100; ++i) {
        for (int j = 3, l = (int)sqrt(i); j <= l; j += 2) {
            if (i % j == 0) {
                cout << i << '\t';
                break;
            } 
    } 
    

    What I did:

    Math:

    • Stop when j > sqrt(i), there's no need to go further than that. Note however that sqrt is an expensive function; for your small sample (from 1 to 100), it might (read, will surely) cost you more to use it.
    • Only check odd numbers; do j += 2 instead of incrementing j one by one

    Micro-optimizations:

    • Use ++i instead of i++; the latter has a temporary variable in which it stores the original value of i; the former does not.
    • Print '\t' as a character not as a string "\t".

    (These micro-optimizations are probably made automatically by the compiler anyway, but there's no harm in knowing about them.)

    0 讨论(0)
  • 2021-01-25 02:18

    The most efficient way to accomplish this is the Sieve of Eratosthenes. Here's an incremental version, specifically tailored to producing the primes up to 100, one by one (maximum up to 120, because 121 == 11 * 11).

    int m3 = 9, m5 = 25, m7 = 49, i = 3;
    printf("2 ");
    for( ; i < 100; i += 2 )
    {
        if( i != m3 && i != m5 && i != m7)
            printf("%d ", i);
        else
        {
            if( i == m3 ) m3 += 6;
            if( i == m5 ) m5 += 10;
            if( i == m7 ) m7 += 14;
        }
    }
    
    0 讨论(0)
  • 2021-01-25 02:20

    You are checking every number from 2 to 100. But since 2 is the only even prime number, you can skip every even number after 2. This goes for both i and j. So start i and j at 3, and increment them by 2.

    #include<iostream>
    
    using namespace std;
    
    int main() {
        cout<<"Prime numbers between 1 and 100 are:"<<endl;
        cout<<"2"<<"\t";
        for (int i=3; i<100;i+=2) {
            // This loop stops either when j*j>i or when i is divisible by j.
            // The first condition means prime, the second, not prime.
            int j=3;
            for(;j*j<=i && i%j!=0; j+=2); // No loop body
    
            if (j*j>i) cout << i << "\t";
        }
        cout<<endl;
        return 0;
    }
    

    In addition to the trick mentioned above, I've added the condition j*j<=i which logically is the exact same as j<=sqrt(i). There's no need to compute the square root when you can do a simple multiplication.

    0 讨论(0)
  • 2021-01-25 02:24
        for(int j=2;j<i;j++){
    

    This one is not nice.

    First of all, you only need to check for j <= sqrt(i), as for example 7 will never divide 12 without a rest.

    Second, you should keep track of all previously found prime numbers; keep it in vector and only do this loop for it's contents and for that condition I wrote.

    0 讨论(0)
  • 2021-01-25 02:31

    You could optimise your existing code:

    • In the while loop you should have a step of 2, so that you do not test the even numbers.
    • In your for loop you should stop when you reach the square root of the number you are testing

    You could use a different method:

    • Sieve of Erastoses: http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes

    On the Sieve of Erastoses just removing the numbers divisable by 2,3 and 5 would significantly reduce the number of times you need to test for primality.

    0 讨论(0)
提交回复
热议问题