10/29
今天看了java 核心技术 卷1 基础知识 的集合部分,对集合的架构有了重新的认识,只能说,真的要学习的地方太多了,今天主要学习到了一个算法:
埃拉托色尼筛法——求一定范围内的素数,书本上介绍的是这种方法并不是最优秀求素数的方法,但是他很经典,所以被记载在这本书上,在java里面,这种方法主要通过bitset也就是位集合来实现,通过先把位全部置“开”状态,然后通过循环来使得非素数的位为“关”状态,最后记录共有几个开状态的位,就可以得出这个范围里面素数的多少,具体代码如下:
!注意:这个代码十分经典,建议背一下
public class Sieve {
public static void main(String[] args) {
int n= 2000000;
long start = System.currentTimeMillis();
var bitSet = new BitSet(n+1);
int count =0;
int i;
for(i=2;i<=n;i++)
bitSet.set(i);
i=2;
while (i*i<=n){
if (bitSet.get(i)){
count++;
int k=2*i;
while (k<=n){
bitSet.clear(k);
k+=i;
}
}
i++;
}
while (i<=n){
if (bitSet.get(i))count++;
i++;
}
long end =System.currentTimeMillis();
System.out.println(count+"primes");
System.out.println((end-start)+"milliseconds");
}
}
其中,这里面代码有一句非常非常经典!
while (i*i<=n){
这句代码的意思,需要想一下才能理解,首先我们是通过一个素数来乘以各种倍数来排除这个范围里面(2-2000000)的非素数,因为素数乘以倍数的数一定不是素数,假设这个素数是i,倍数是j,那就是ij<n(范围的最大值),可以理解i和j是两个指针,一个从下到上递增,一个从上到下递减,当它们准备相遇,也就是i=j的时候,后面是重复的,所以说,ij<n也就可以被改写成i*i<n!!!!我是这么理解这句代码的!可是,很多情况下,理解不代表会用,所以希望能够把这个求素数的方法记下来。
java 核心技术 卷1中的集合部分也需要重复学习,真的太精华了。