Eratosthenes算法筛选的时间复杂度

时间:2010-04-06 05:06:23

标签: algorithm performance time-complexity sieve-of-eratosthenes

来自Wikipedia:

  

算法的复杂性是   O(n(logn)(loglogn))位操作。

你是如何达到的?

复杂性包括loglogn术语告诉我某个地方有sqrt(n)


假设我在前100个数字(n = 100)上运行筛子,假设将数字标记为复合需要恒定时间(数组实现),我们使用mark_composite()的次数将是

之类的东西
n/2 + n/3 + n/5 + n/7 + ... + n/97        =      O(n^2)                         

要查找下一个素数(例如,在越过7的倍数的所有数字后跳转到5,操作数将为O(n)

因此,复杂性将是O(n^3)你同意吗?

5 个答案:

答案 0 :(得分:105)

  1. 你的n / 2 + n / 3 + n / 5 + ... n / 97不是O(n),因为术语数不是常数。 [编辑后编辑:O(n 2 )上限过松。]松散的上限是n(1 + 1/2 + 1/3 + 1/4 + 1 / 5 + 1/6 + ... 1 / n)(所有数字到n的倒数之和),即O(n log n):见Harmonic number。更合适的上限是n(1/2 + 1/3 + 1/5 + 1/7 + ...),即素数到n的倒数之和,即O(n log log n)。 (请参阅herehere。)

  2. “找到下一个素数”位只有O(n)整体,amortized - 您将继续前进,在总计中仅查找下一个数字n次,而不是每一步。所以这个算法的整个部分只需要O(n)。

  3. 因此,使用这两个,你得到O(n log log n)+ O(n)= O(n log log n)算术运算的上界。如果你计算位操作,因为你处理的数字最多为n,它们有大约log n位,这是log n的因子进来,给出O(n log n log log n)位操作。

答案 1 :(得分:8)

  

复杂性包括loglogn术语告诉我某个地方有一个sqrt(n)。

请注意,当您在筛选时找到素数P时,您不会在当前位置+ P开始交叉数字;你实际上开始在P^2处勾选数字。所有P小于P^2的倍数都将被之前的素数划掉。

答案 2 :(得分:7)

  1. 内部循环执行n/i步骤,其中i为prime =>整体 复杂度为sum(n/i) = n * sum(1/i)。根据泛音 系列sum (1/i)其中i为素数为log (log n)。在 总计,O(n*log(log n))
  2. 我认为可以通过将n替换为sqrt(n)来优化上层循环,这样整体时间复杂度将为O(sqrt(n)loglog(n))

    void isprime(int n)
    {
        int prime[n],i,j,count1=0;
        for(i=0;i<n;i++)
        {
           prime[i]=1;
        }
        prime[0]=prime[1]=0;
        for(i=2;i<=n;i++)
        {
            if(prime[i]==1)
            {
                printf("%d ",i);
                for(j=2;(i*j)<=n;j++)
                    prime[i*j]=0;
            }
        }    
    }
    

答案 3 :(得分:1)

int n = 100;
int[] arr = new int[n+1];  
for(int i=2;i<Math.sqrt(n)+1;i++) {
  if(arr[i] == 0) {
    int maxJ = (n/i) + 1;
    for(int j=2;j<maxJ;j++)
    {
      arr[i*j]= 1;
    }
  }
}
for(int i=2;i<=n;i++) {
  if(arr[i]==0) {
    System.out.println(i);
  }
}

对于所有 i>2,Ti = sqrt(i) * (n/i) => Tk = sqrt(k) * (n/k) => Tk = n/sqrt(k)

当 k=sqrt(n) => n[ 1/sqrt(2) + 1/sqrt(3) + ...] = n * log(log(n)) => O(nloglogn) 时循环停止

答案 4 :(得分:0)

请参阅上面的解释,内部循环是直到sqrt(n)的所有质数的谐波和。因此,的实际复杂度为O(sqrt(n)* log(log(sqrt(n))))