先贴代码
#include<stdio.h>
int a[1000];
int main(){
int i,j;
for(i=2;i<=1000;i++)//素数是大于1的,切记。判断可以写成i<=500,省一半循环
if(a[j]==0)//如果没被标记
for(j=i+i;j<=1000;j+=i){//j是i的倍数
a[j]=1;//标记
}
for(i=2;i<=1000;i++)
if(a[i]==0)
printf("%d ",i);
return 0;
}
再介绍下算术基本定理:
百度百科:
https://baike.baidu.com/item/算术基本定理/10920095?fr=aladdin
就是说不是素数的数,都可以表示成素数的有限次方的乘积
例如18 = 21*32
也就是说,2的倍数都不是质数,在2和4之间幸存的3的就是质数,那么3的
倍数也不是质数,在2和3都没筛到的5就是质数,那么5的倍数不是质数。。。。。反复如此,我们就能用一个数组来表示一个数是不是质数(用被判断的数当下标即可)
目前这个算法的时间复杂度是O(f(n2))(不知道是用O还是Ω来表示…)
仔细观察这个算术基本定理,我(看别的文章 ) 发现第二个循环可以写成
i乘i
也就是说
#include<stdio.h>
#include<math.h>
int a[1000];
int main(){
int i,j;
for(i=2;i<=sqrt(1000);i++)//素数是大于1的,切记。判断可以写成i<=500,省一半循环
if(a[j]==0)//如果没被标记
for(j=i*i;j<=1000;j+=i){//j是i的倍数
a[j]=1;//标记
}
for(i=2;i<=1000;i++)
if(a[i]==0)
printf("%d ",i);
return 0;
}
时间复杂度可以直接变成O(nloglogn)
反正我不会证明为什么复杂度是这样的
但是我能理解为啥可以用i2开始跑因为 i 到 i^2 之间的非质数是不再需要用
i 乘上某个比 i 小的数表示了
就是说,跑到 i 的时候,所有比 i 小的数都被跑一遍了,举个例子来说,35=5*7,那么35这个数早在5的时候就跑完了,而不再需要从7开始跑了,因为35不需要再被表示成7乘5;