找到第n个素数

时间:2013-02-07 02:24:48

标签: java performance algorithm complexity-theory primes

我在下面编写了以下代码来查找第n个素数。这可以改善时间复杂度吗?

说明

ArrayList arr存储计算的素数。一旦arr达到'n'大小,循环退出,我们检索ArrayList中的第n个元素。在计算素数之前添加数字2和3,并且从4开始的每个数字都被检查为素数。

public void calcPrime(int inp) {
    ArrayList<Integer> arr = new ArrayList<Integer>(); // stores prime numbers 
                                                      // calculated so far
    // add prime numbers 2 and 3 to prime array 'arr'
    arr.add(2); 
    arr.add(3);

    // check if number is prime starting from 4
    int counter = 4;
     // check if arr's size has reached inp which is 'n', if so terminate while loop
    while(arr.size() <= inp) {
        // dont check for prime if number is divisible by 2
        if(counter % 2 != 0) {
            // check if current number 'counter' is perfectly divisible from 
           // counter/2 to 3
            int temp = counter/2;
            while(temp >=3) {
                if(counter % temp == 0)
                    break;
                temp --;
            }
            if(temp <= 3) {
                arr.add(counter);
            }
        }
        counter++;
    }

    System.out.println("finish" +arr.get(inp));
    }
}

3 个答案:

答案 0 :(得分:10)

你的算法做了 O(n ^ 2)操作(也许我不准确,但似乎是这样), 结果是 n

http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes算法采用 O(ipn * log(log(n)))。您只能在其中执行 inp 步骤,并假设 n = 2ipn * ln(ipn) n 应该大于 ipn -prime。 (我们知道素数的分布http://en.wikipedia.org/wiki/Prime_number_theorem

无论如何,您可以改进现有的解决方案:

public void calcPrime(int inp) {
    ArrayList<Integer> arr = new ArrayList<Integer>();
    arr.add(2);
    arr.add(3);

    int counter = 4;

    while(arr.size() < inp) {
        if(counter % 2 != 0 && counter%3 != 0) {
            int temp = 4;
            while(temp*temp <= counter) {
                if(counter % temp == 0)
                    break;
                temp ++;
            }
            if(temp*temp > counter) {
                arr.add(counter);
            }
        }
        counter++;
    }

    System.out.println("finish" +arr.get(inp-1));
    }
}

答案 1 :(得分:2)

您可以采取一些措施来加快速度:

  1. 在5处开始计数器并将其递增2而不是1,然后不要在循环中检查mod 2.
  2. 而不是在counter / 2处启动temp,而是在第一个奇数&lt; = int(sqrt(counter))
  3. 启动它
  4. 减去2点的温度。
  5. 我不确定它是否会提高复杂度,但上述(2)将从O(n ^ 2)变为O(n * sqrt(n))

答案 2 :(得分:0)

  public静态void Main()
    {
        Console.Write(“输入数字:”);
        整数
        int [] arr =新的int [10000];
        num = Convert.ToInt32(Console.ReadLine());
        int k;
        k = 0;
        int t = 1;
        对于(int j = 1; j <10000; j ++)
        {
            对于(int i = 1; i <= j; i ++)
            {
                如果(j%i == 0)
                {
                    k ++;
                }
            }
            如果(k == 2)
            {
                arr [t] = j;
                t ++;
                k = 0;
            }
            其他
            {
                k = 0;
            }
        }
        Console.WriteLine(“第N个素数。{0}”,arr [num]);
        Console.ReadLine();
    }