筛选法(求1~n中的质数)
用来除以2的倍数,是合数就置为0.
用来除以3的倍数,是合数就置为0.
用来除以4的倍数,是合数就置为0.
…
用来除以√n的倍数,是合数就置为0.
void isPrime(int n){
int[] arrays=new int[N+1];
for(int i=1;i<N+1;i++){
arrays[i]=i; //数组里面的就安排1到100的数。
}
arrays[1]=0; //1不是质数,先“挖”掉
for(int i=2;i<=(int)Math.sqrt(n);i++){
for(int j=i;j*i<=n;j++){
arrays[j*i]=0; //i的倍数就置为0
}
}
for(int i=2;i<=N;i++){
if(arrays[i]!=0){
System.out.print(arrays[i]);
}
}
}
问题1:
为什么j=i.
答:由矩阵图我们可以很清楚地得知,有些数值有重复的部分,原因是该数的最小因子有很多。所以我们取对角线开始,就能避免很多重复值。
其实这个算法是数学问题。列出计算过程:
j/i | 2 | 3 | 4 | 5 | … | 10 |
---|---|---|---|---|---|---|
2 | a[4] | a[6] | a[8] | a[10] | ||
3 | a[6] | a[9] | a[12] | a[15] | ||
4 | a[8] | a[12] | a[16] | a[20] | ||
5 | a[10] | a[15] | a[20] | a[25] | ||
… | … | … | … | … | … | … |
n/i | a[98] | a[99] | a[100] | a[100] | a[100] |
问题2:
i<=(int)Math.sqrt(n)。
答:原来是比较到100的,但是有一个数学公式(超过这个范围就会重复)。这个比较常见,想理解的可以去百度。
问题3:
为什么1的倍数(1,2,3,4,5,6,7,8,100)不要.
答:因为所有数的都在1-100这个范围之中,肯定满足被自己整除这个条件。
要是1的倍数算的话,就会造成所有值都会标记为0.所以你懂得。
问题4:
前面你说过了,j=i。那i=5时,就有a[5*5]=0.那你怎么首先保证5就是质数呢?
答:这个问题问的好! i=5时,前面i=2时,i=3时,i=4时已经在计算其倍数了,其中并没有值为5.
因为质数只能被1和它本身整除,如果1和它之间的数,不能整除它,说明其为质数。
所以从这个角度来去考虑的话,i=2时,已经判断a[4]不是质数了
所以当i=4时,其已经被判断过了,所以不用担心这个问题。
程序后一步的运行是以前面一步为前提的!
总结
程序本身还是存在一些不足,i=2时已经能够判断大量的偶数出来了,后面的i++又重复判断!。
所以读者有兴趣的话,可以看看6+1筛选法。
推荐博客,图解法,清晰易懂
https://blog.youkuaiyun.com/zrcshendustudy/article/details/86563525