#include<stdio.h>
#include<time.h>
int main()
{
clock_t start;
double d;
long int n,i,j;
scanf("%ld",&n);
n=100000;
j=2;
start=clock();
printf("\n%ld",j);
for(j=3;j<=n;j+=2)
{
for(i=3;i*i<=j;i+=2)
if(j%i==0)
break;
if(i*i>j)
printf("\n%ld",j);
}
d=(clock()-start)/(double)CLOCKS_PER_SEC;
printf("\n%f",d);
}
对于上述程序,当n = 100000时,我的运行时间为0.015秒。 我还在C中实现了Eratosthenes算法的Sieve,并且在n = 100000时获得了0.046的运行时间。
我的上述算法如何比我实施的Sieve算法更快。
上述程序的时间复杂度是多少?
我的筛选实施
#define LISTSIZE 100000 //Number of integers to sieve<br>
#include <stdio.h>
#include <math.h>
#include <time.h>
int main()
{
clock_t start;
double d;
long int list[LISTSIZE],i,j;
int listMax = (int)sqrt(LISTSIZE), primeEstimate = (int)(LISTSIZE/log(LISTSIZE));
for(int i=0; i < LISTSIZE; i++)
list[i] = i+2;
start=clock();
for(i=0; i < listMax; i++)
{
//If the entry has been set to 0 ('removed'), skip it
if(list[i] > 0)
{
//Remove all multiples of this prime
//Starting from the next entry in the list
//And going up in steps of size i
for(j = i+1; j < LISTSIZE; j++)
{
if((list[j] % list[i]) == 0)
list[j] = 0;
}
}
}
d=(clock()-start)/(double)CLOCKS_PER_SEC;
//Output the primes
int primesFound = 0;
for(int i=0; i < LISTSIZE; i++)
{
if(list[i] > 0)
{
primesFound++;
printf("%ld\n", list[i]);
}
}
printf("\n%f",d);
return 0;
}
答案 0 :(得分:3)
有很多事情可能会影响您的结果。当然,我们需要查看筛选实现的代码。此外,您计算机上clock
功能的分辨率是多少?如果实现不能在毫秒级别实现高精度,那么您的结果可能在测量误差范围内。
我怀疑问题出在这里:
//Remove all multiples of this prime
//Starting from the next entry in the list
//And going up in steps of size i
for(j = i+1; j < LISTSIZE; j++)
{
if((list[j] % list[i]) == 0)
list[j] = 0;
}
这是一种删除素数的所有倍数的糟糕方法。为什么不使用内置乘法运算符来删除倍数?这个版本应该快得多:
//Remove all multiples of this prime
//Starting from the next entry in the list
//And going up in steps of size i
for(j = list[i]; j < LISTSIZE; j+=list[i])
{
list[j] = 0;
}
答案 1 :(得分:1)
上述程序的时间复杂度是多少?
要凭经验测量程序的时间复杂度,您需要多个数据点。为多个N值运行程序,然后绘制N与时间的关系图。您可以使用电子表格,GNUplot或方格纸和铅笔来完成此操作。您还可以使用软件和/或普通旧数学来查找适合您数据的多项式曲线。
非经验性:关于分析计算复杂性已经写了很多(并在计算机科学课上讲授)。关于computational complexity theory的维基百科文章可能为进一步阅读提供了一些起点。
答案 2 :(得分:0)
您的筛选实施不正确;这就是它如此缓慢的原因:
答案 3 :(得分:0)
仅为您的时间复杂性:
你有一个~LISTMAX迭代的外循环和一个最大的内循环。 LISTSIZE迭代。这意味着您的复杂性
O(SQRT(N)×n)的
其中n = listsize。它实际上有点低,因为内部循环每次都会减少它的计数,并且仅针对每个未知数量运行。但这很难计算。由于O-Notation提供了上限,因此O(sqrt(n)* n)应该没问题。
答案 4 :(得分:0)
这种行为很难预测,但你应该考虑到访问内存并不便宜......对于小素数来说再次计算它可能会更快。
答案 5 :(得分:0)
那些运行时间太小而无意义。系统时钟分辨率不准确到那种水平。
如何获取准确的计时信息,请在循环中运行算法。重复几千次以使运行时间达到至少一秒,然后你可以将时间除以循环次数。