C 查找素数10001优化问题

C 查找素数10001优化问题,c,C,所以我创建了一个程序来查找第10001个素数。以下是该计划的主要内容: int main(){ inti; int j; 整数计数=0; int currnumber=0; 对于(i=1;计数=sqrt(number)当且仅当它有一个除数如果我理解正确,您将取每一个小于1001的数字,并检查它是否有一个公分母。这是非常缓慢的。其复杂性实际上呈指数级增长。你应该做的是把这个方法和筛子结合起来。取你用公分母法找到的任何素数,将它们从1到n相乘,直到它们的倍数都在1到10001之间。这样,您将跳过对已

所以我创建了一个程序来查找第10001个素数。以下是该计划的主要内容:

int main(){

inti;
int j;
整数计数=0;
int currnumber=0;
对于(i=1;计数<10002;i++){
如果(i){
计数++;
currnumber=i;
如果(计数=10002)
printf(“%i”,货币编号);
}
}
}
下面是我在自定义库中构建的iPrime函数的代码:

long long isPrime(long long number){

    long long i = 2;

    if(number == 2)
        return 1;

    for(i=2;i<number;i++){

        if(number % i == 0)
            return 0;



    }
    if(i >= number && ((number % 1 == 0) && (number % number == 0)))
        return 1;
}
long-long iPrime(长数字){
长i=2;
如果(数字==2)
返回1;
对于(i=2;i=number&((number%1==0)&&(number%number==0)))
返回1;
}
当我运行这个程序时,它会运行并给出正确的答案(这是一个Euler问题,所以我知道我做得对:D),但至少需要6秒的时间来处理。因此,我的问题是:

  • 为什么要花那么长时间?这与我如何设置算法有关吗
  • 如何改进代码以使其运行更快

  • 提前谢谢

    您可以做的第一件事可能是缓存您创建的素数值,并使用该算法,以便在找到素数值后不必不断重新计算它们。

    您正在使用两个for循环


    我想到的一个更快的方法,也是一个很好的练习,就是算法:

    可以做很多优化。有几个人提到了埃拉托什尼筛,这是正确的,但让我给你一些额外的提示

    在不改变算法的情况下改进代码:正如Michael Parker提到的,您不需要处理偶数,因为偶数中只有一个是素数(数字2,它是所有素数中“最奇怪”的一个,这是一个双关语)。您可以通过避免三的倍数来实现类似的技巧,这归结为只处理整数
    i
    ,它们比6的倍数多1或5。要将其转换为代码,首先将
    count
    设置为3,以说明素数2、3和5。然后从6开始
    i
    ,测试
    i+1
    i+5
    (都在
    for
    循环中),然后每次将
    i
    增加6


    对于
    isPrime()
    您可以添加类似的改进,但也可以在达到数字的平方根后停止尝试除法。这是因为
    number
    有一个除数>=
    sqrt(number)
    当且仅当它有一个除数如果我理解正确,您将取每一个小于1001的数字,并检查它是否有一个公分母。这是非常缓慢的。其复杂性实际上呈指数级增长。你应该做的是把这个方法和筛子结合起来。取你用公分母法找到的任何素数,将它们从1到n相乘,直到它们的倍数都在1到10001之间。这样,您将跳过对已找到的所有素数的倍数测试公共分母方法。例如,尝试以下方法:

    ArrayList<Integer> List = new ArrayList<Integer>();
    ArrayList<Integer> Primes = new ArrayList<Integer>();
    Primes.add(2);
    Integer p=2;
    Integer n=105000;
    Integer i=1;
    
    while(p < n) {
        i=1;
        while((p*i)<=n){
            List.add(p*i);
            i++;
        }
        while (p < n){
        p++;
        if(List.contains(p)){}
        else {Primes.add(p); break;}
        }
    }
    
    System.out.println(Primes.get(10000));
    
    ArrayList List=new ArrayList();
    ArrayList Primes=新的ArrayList();
    添加(2);
    整数p=2;
    整数n=105000;
    整数i=1;
    而(p而((p*i)查找“素数筛”并编写一个简单的筛子。你的筛子会做很多不必要的测试(例如,一旦我们测试了一个数字不能被2整除,为什么还要测试任何偶数?)。这个问题更适合于(i=2;i可能的重复项他不是要求用最快的方法找到N以下的所有素数,而是要求用最快的方法找到第N个素数。这是不同的。列表不是最好的数据结构。首先,它将包含重复项,这会使您的空间膨胀--O(N^2)memory.Set更接近您想要的,但是当您评估运行时间时,您需要考虑插入到集合中并检查包含的时间。最终,筛选的最佳数据结构只是一个数组:它既节省时间又节省内存。我使用数组列表的原因是因为我必须实例化创建一个新数组以向其中添加元素。
    
    ArrayList<Integer> List = new ArrayList<Integer>();
    ArrayList<Integer> Primes = new ArrayList<Integer>();
    Primes.add(2);
    Integer p=2;
    Integer n=105000;
    Integer i=1;
    
    while(p < n) {
        i=1;
        while((p*i)<=n){
            List.add(p*i);
            i++;
        }
        while (p < n){
        p++;
        if(List.contains(p)){}
        else {Primes.add(p); break;}
        }
    }
    
    System.out.println(Primes.get(10000));