通过嵌套循环

时间:2015-08-07 20:06:12

标签: algorithm

有没有办法在不实际使用嵌套循环的情况下找到介于0到100之间的所有素数,即时间复杂度小于n ^ 2。我确实尝试过递归,但它仍然是相同的复杂性。任何人都可以帮忙。 感谢

4 个答案:

答案 0 :(得分:4)

一个非常有用的实现是预先计算列表。

my @primes = (
   2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41,
   43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97,
);

say for @primes;

很明显吗?也许,但我敢打赌,许多人即将发布更复杂,更慢的解决方案。

答案 1 :(得分:1)

是的,请查看Seive of Atkin,这是Sieve of Eratosthenes的优化版本。

Python实施:

import math

def sieveOfAtkin(limit):
    P = [2,3]
    sieve=[False]*(limit+1)
    for x in range(1,int(math.sqrt(limit))+1):
        for y in range(1,int(math.sqrt(limit))+1):
            n = 4*x**2 + y**2
            if n<=limit and (n%12==1 or n%12==5) : sieve[n] = not sieve[n]
            n = 3*x**2+y**2
            if n<= limit and n%12==7 : sieve[n] = not sieve[n]
            n = 3*x**2 - y**2
            if x>y and n<=limit and n%12==11 : sieve[n] = not sieve[n]
    for x in range(5,int(math.sqrt(limit))):
        if sieve[x]:
            for y in range(x**2,limit+1,x**2):
                sieve[y] = False
    for p in range(5,limit):
        if sieve[p] : P.append(p)
    return P

print sieveOfAtkin(100)

答案 2 :(得分:1)

从O(n ^ 2)不完全改善 但您可以像这样缩小搜索范围: 素数&gt; 6有一个属性。它们是6n + 1或6n-1(并不意味着所有6n + 1或6n-1都是素数)  所以你的代码看起来像是:

/ **  * @author anirbanroy  * /

object PrimeNumberPrinter {

def main(args: Array[String]) {
var count: Int = 0
var initialPrimeNumberCount: Array[Int] = Array(0, 0, 1, 2, 2)
println("Enter a range: ")
val input = io.StdIn.readInt()
if (input > 4) {
  count = 2;
  for (i <- 5 to input by 6) {
    if (i + 2 <= input) {
      if (isPrime(i + 2)) {
        count = count + 1
      }
    }
    if (i <= input) {
      if (isPrime(i)) {
        count = count + 1
      }
    }
  }

  println("No of prime numbers: " + count)

} else {
  println("No of prime numbers are: " + initialPrimeNumberCount(input))
}

}

def isPrime(value: Int): Boolean = {
val range: Int = round(sqrt(value).toFloat)
 for (j <- 2 to range) {
   if (value.%(j) == 0)
     return false
  }
  return true
}

答案 3 :(得分:0)

蛮力解(试图将所有奇数除数除以所有奇数除数)并不具有复杂度O(N²),而是O(N√N),因为当暂定除数超过{时,搜索可以停止已达到{1}}。

通过使用已经识别的素数而不是所有奇数整数,您可以非常轻松地降低这种复杂性。给定素数的密度函数,您将减少到√N

无论如何,对于O(N√N/Log(N))小到N这个&#34;优化&#34;因为100仅为√N且要考虑的主要除数为10,而奇数除数为3, 5, 7,所以并不重要。

这是一个简单的实现,尝试三个除数,并且在3, 5, 7, 9时不会尝试停止,因为这会增加昂贵的条件分支。

i>√N

从技术上讲,此代码是纯N= 100 print 2, 3, 5, 7, for i in range(3, N, 2): if i % 3 != 0 and i % 5 != 0 and i % 7 != 0: print i, ,但仅适用于O(N)。通过直接计数,当使用N<121的快捷方式评估时,它会执行完全106模运算。