找到第10000个素数

时间:2014-11-06 23:06:57

标签: c

这是我查找第10000个素数的代码,但它真的很慢,计算需要7秒。

#include <stdio.h>
#include <stdlib.h>

long int prime (int n)
{
    int i;
    for(i=2;i<n;i++)
    {
        if(n%i==0)
        return 0;
    }
    return 1;
}

int main()
{
    int i=2,counter=0;
    while(1)
    {
        if(prime(i))
        counter++;
        if(counter==10000)
        break;
        i++;
    }
    printf("10000th prime number is: %d",i);
}

这是蛮力方法,所以这可能是为什么它如此缓慢的原因。 我认为问题可能是它必须多次调用函数。那么你认为它可以被优化,或者最好为此找到一些数学公式。

3 个答案:

答案 0 :(得分:0)

稍微优化您的代码(根据评论进行更改):

long int prime (int n)
{
  int i;
  int e = (int)sqrt(n);
  for(i=2; i<=e;i++)
  {
    if(n%i==0)
    return 0;
  }
  return 1;
}

答案 1 :(得分:0)

您可以通过对prime()进行以下更改来大幅减少时间:

  1. 停在sqrt(n)
  2. i=3开始,i增加2
  3. 这是一个包含两个版本和每个版本所用时间的程序。

    #include <stdio.h>
    #include <time.h>
    #include <stdlib.h>
    #include <math.h>
    
    int is_prime1 (int n)
    {
        int i;
        for(i=2;i<n;i++)
        {
            if(n%i==0)
            return 0;
        }
        return 1;
    }
    
    void do_it1(int max)
    {
       clock_t start = clock();
       clock_t end;
    
       int i=2,counter=0;
       while(1)
       {
          if(is_prime1(i))
             counter++;
          if(counter==max)
             break;
          i++;
       }
       end = clock();
    
       printf("%dth prime number is: %d\n", max, i);
       printf("Time taken: %lf\n", 1.0*(end-start)/CLOCKS_PER_SEC);
    }
    
    int is_prime2 (int n)
    {
        int i;
        int stop = sqrt(n);
        for(i=3;i<=stop;i+=2)
        {
            if(n%i==0)
            return 0;
        }
        return 1;
    }
    
    void do_it2(int max)
    {
       clock_t start = clock();
       clock_t end;
    
       int i=3,counter=1;
       while(1)
       {
          if(is_prime2(i))
             counter++;
          if(counter==max)
             break;
          i += 2;
       }
       end = clock();
    
       printf("%dth prime number is: %d\n", max, i);
       printf("Time taken: %lf\n", 1.0*(end-start)/CLOCKS_PER_SEC);
    }
    
    int main(int argc, char** argv)
    {
       int max = atoi(argv[1]);
       do_it1(max);
       do_it2(max);
    }
    

    示例执行:

    ./test 10000
    

    示例输出:

    10000th prime number is: 104729
    Time taken: 9.469000
    10000th prime number is: 104729
    Time taken: 0.078000
    

答案 2 :(得分:-1)

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

int *prime;
int prime_n;

void make_prime_table(int n){
    prime = malloc(sizeof(int) * n / 2);
    prime_n =0;
    prime[prime_n++] = 2;
    prime[prime_n++] = 3;
    int i, j;
    for(i = 5; i <= n; i +=2){
        bool is_prime = true;
        for(j = 1; j < prime_n ; ++j){
            int t = prime[j];
            if(t * t > i)
                break;
            if(i % t == 0){
                is_prime = false;
                break;
            }
        }
        if(is_prime)
            prime[prime_n++] = i;
    }
}

int main(void){
    int n = 105000;
    make_prime_table(n);
    if(prime_n >= 10000)
        printf("10000th prime number is: %d\n", prime[9999]);

    free(prime);
    return 0;
}