这是我的第二篇文章,我的想法是把自己再学习的路上遇到的困难都给记录下来,一来是方便以后的自我复习,二来就是大家资源共享,帮助和我一样遇到困难的小伙伴们。
素数又称质数。
首先,我们来看一下素数(质数)的定义:一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做素数;
第一种: 看到这里我们就可以用一种 列举 的方法判断它是否为素数。
1到100以内的素数如下表:
思路最清晰,但是速度最慢,在某些oj上可能会超时。
原理就是让这个数n%(2 3 4 5 6······n-1)然后判断是否为0
如果再取余的过程中有只要存在一个成立的话,那这个数就不是质数。
代码如下:
import java.util.Scanner;
public class Tast01 {
public static void main(String[] args) {
Scanner arr=new Scanner(System .in );
int n=arr.nextInt();
boolean a=false; //用于记录
for (int i = 2; i <n; i++) { //除 2--n-1
if(n%i==0) {
System.out.println("不是质数");
a=true;
break; //结束循环,防止输出多个“不是素数”
}
}
if(a==false) {
System.out.println("是质数");
}
}
}
第二种:与上面类似,原理就是让这个数n%(2 3 4 5 6······根号n)然后判断是否为0
这里比较难以理解,大家看下图就可以知道了。
也就是说,300除到15理论上就可以清楚哪些数据可以整除了。所以我们让n%(2 3 4 5 6······根号n)然后判断是否为0。 根号n=Math.sqrt(n)
这里要注意:调用Math.sqrt()这一函数的时候时间上也是有不少的消耗品的,所以我们可以将 i<n变为 i*i<n,但是i*i如果太大可能会超出int 的范围,所以这里我们将int i转为long i。
还可以在此基础上做修改 :n%( 3 5 7 9 11 13 ······根号n)将i++变为i+=2 需要单独判断一下2,这一数字.
代码如下:
import java.util.Scanner;
public class Tast03 {
public static void main(String[] args) {
Scanner arr=new Scanner(System .in );
int n=arr.nextInt();
boolean a=false; //用于记录
if(n==2) {
System.out.println("不是质数");
}
for (long i = 3; i*i <n; i+=2) { //除 2--n-1
if(n%i==0) {
System.out.println("不是质数");
a=true;
break; //结束循环,防止输出多个“不是素数”
}
}
if(a==false) {
System.out.println("是质数");
}
}
}
第三种:标准的爱拉托逊斯筛选法-------本段截取 素数判断的几种方法代码实现及其复杂度分析 - 百度文库
爱拉托逊斯筛选法(以下简称筛法)是一种高效的判断素数的方法。能够一次性的筛选出某个区间的素数。其算法原理本质还是充分利用了素数的定义,即素数的约数只有1和它本身。如果某个数m是另一个数n的倍数,则说明m肯定不是素数。所以我们只要在某个范围内,将已知素数的所有倍数都筛去,剩下的肯定是素数。因为只有它不是其他数的倍数(1和本身除外)具体做法是:先把N个自然数按次序排列起来。1不是质数,也不是合数,要划去。第二个数2是质数留下来,而把2后面所有能被2整除的数都划去。2后面第一个没划去的数是3把3留下,再把3后面所有能被3整除的数都划去。3后面第一个没划去的数是5把5留下,再把5后面所有能被5整除的数都划去。这样一直做下去,就会把不超过N的全部合数都筛掉,留下的就是不超过N的全部质数。因为希腊人是把数写在涂腊的板上,每要划去一个数,就在上面记以小点,寻求质数的工作完毕后,这许多小点就像一个筛子,所以就把埃拉托斯特尼的方法叫做“埃拉托斯特尼筛”,简称“筛法”。(另一种解释是当时的数写在纸草上,每要划去一个数,就把这个数挖去,寻求质数的工作完毕后,这许多小洞就像一个筛子。)
public class Tast04 {
public static void main(String[] args) {
int max = 1000000000;
Tast04 pn = new Tast04();
pn.sieveOfEratosthenes(max);
}
boolean[] sieveOfEratosthenes(int max){
boolean[] flags = new boolean[max+1];
int count = 0;//统计一共有多少个素数
int prime = 2;
//初始化,设置flags数组全部为true
for (int i = 0; i < max; i++) {
flags[i] = true;
}
flags[0] = flags[1] = false;
while (prime <= max) {
//剔除prime的倍数
crossOff(flags, prime);
//找出下一个为true的值
prime = getNextPrime(flags, prime);
if (prime >= flags.length) {
break;
}
count++;
System.out.println("prime = "+prime);
}
System.out.println("count = "+count);
return flags;
}
void crossOff(boolean[] flags,int prime){
/*
* 剔除余下的prime倍数的数字,从prime*prime开始,因为如果k*prime且k<prime,
* 在之前的迭代中已经被剔除了
*/
for (int i = prime*prime; i < flags.length; i+=prime) {
flags[i] =false;
}
}
int getNextPrime(boolean[] flags,int prime){
int next = prime + 1;
while (next < flags.length && !flags[next]) {
next++;
}
return next;
}
}
谢谢大家!