内容摘要:
- 明确素数到底是啥数。
- 埃式筛法是干嘛用的。
- 利用java实现埃式筛法的思路。
- 利用埃式筛法解决PAT_1013_B 题。
素数(prime number)到底是啥数:
定义:
在大于1的自然数中,除了1和它本身以外不能再被其他数所整除。
实例化定义:
- 3是素数,因为它不可以被除了“1”以及自身“3”之外的数所整除。
- 10不是素数,因为它除了“1”以及自身“10”之外,还可以被"2",“5”等数字所整除,所以他不是素数。我们也叫他“合数”(composite number)。
需要注意:
- 2是最小的素数。
- "素数"和"质数"是同一样东西。
埃式筛法是干什么用的:
作用:
从一堆自然数里面,找出这一堆自然数里面的所有的素数。
实例化:
- 前提:a[]={1,2,3,4,5,6,7,8,9...29},prime[]={}。
- 通过: 埃式筛法从数组a中筛选出所有的素数,并且把他们放进数组prime[]中。
- 得到:prime[]={2,3,5,7,11,13,19,23,29}。
利用java实现埃式筛法的思路:
首先明确算法主要的依据以及两个前提:
主要的依据:任何一个合数,一定有比他小的素数因子。(大家可以利用小时候学的分解自然数的过程去理解一下这句话)
- 默认2是已知的最小的素数
- 任何素数的倍数都不是素数,比如已经"2"是素数,但是2的倍数,例如4,6,8,10,12...都一定不是倍数,因为"倍数"就是可以整除这个数的因子。
对范围在2~100的数应用埃式筛法筛选出这里面的所有素数的过程:
装有2~100自然数的数组的最初状态。
2是素数,标记所有2的倍数。从4开始。
3在上一步没有被标记,所以3是素数。标记所有3的倍数,从9开始。
5是素数,标记所有5的倍数,从25开始
7是素数,标记所有7的倍数,从49开始
11的平方,超过了100,在数组里面所有没有被标记的数字都是素数
最终得到的结果
转化成代码的几个关键部分:
1.利用boolean类型的素组去标记非素数
2.算法由嵌套的两层循环组成
- 外层:寻找未被标记的元素(素数)
- 内层:把素数的倍数标记为合数(composite)
java代码(找出自然数upperBound内,包括upperBound的所有的素数,并且把它们输出)
1 public void runEratosthenesSieve(int upperBound) { 2 int upperBoundSquareRoot = (int) Math.sqrt(upperBound); 3 /*这里取平方是因为通过数学推理可以知道只需要判断到upperBound的上界即可。 4 第一次写的读者可以把循环的次数设置成upperBound,便于理解*/ 5 boolean[] isComposite = new boolean[upperBound + 1]; 6 //这个boolean类型的数组是为了标记upperBound以内的自然数 7 8 for (int m = 2; m <= upperBoundSquareRoot; m++) { 9 if (!isComposite[m]) { 10 System.out.print(m + " "); 11 for (int k = m * m; k <= upperBound; k += m) 12 isComposite[k] = true; 13 } 14 } 15 for (int m = upperBoundSquareRoot; m <= upperBound; m++) 16 if (!isComposite[m]) 17 System.out.print(m + " "); 18 }
题意:输出第M~N个素数。
思路:利用筛法把素数表打印至第N个素数,然后按格式输出。
java代码
1 class Prime1{ 2 private int maxn =100010; 3 private int a[] =new int[maxn]; 4 5 void isPrime(int n){ 6 boolean flag[] = new boolean[maxn]; 7 int index=0; 8 for(int i=2;i<maxn;i++){ 9 if(index>=n) break;//无需找出第n个素数后的素数 10 if(! flag[i]){ 11 a[index]=i; 12 index++; 13 for (int j=2*i;j<maxn;j+=i){ 14 flag[j]=true; 15 } 16 } 17 } 18 } 19 20 void outprint(int m,int n){ 21 int count=0; 22 isPrime(n); 23 for(int i=m-1;i<n;i++){ 24 if(count%10!=0&&i!=n-1){ 25 System.out.print(a[i]+" "); 26 }else{ 27 System.out.println(); 28 } 29 } 30 } 31 }