质数又叫素数,是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。
常见方法
根据质数定义用小于i大于1的所有数对变量i进行取余,若只有变量i本身能取余为0则说明变量i为质数。
代码如下:
public class ZhiShu {
public static void main(String[] args) {
boolean flag = true;
long start = System.currentTimeMillis();
for (int i = 2;i<= 100;i++){
for(int j = 2;j<i;j++){
if (i%j == 0){
flag = false;
break;
}
}
if (flag == true){
System.out.println(i);
}
flag = true;
}
long end = System.currentTimeMillis();
System.out.println("所用时间"+(end - start)+"ms");
}
}
输出结果:
由于数量过小所以计算时间为0ms,此时要将100改为10万,由于打印输出也需要处理时间,所以仅计算质数个数
代码如下:
public class ZhiShu {
public static void main(String[] args) {
boolean flag = true;
int count = 0;//计算质数个数
long start = System.currentTimeMillis();
for (int i = 2;i<= 100000;i++){
for(int j = 2;j<i;j++){
if (i%j == 0){
flag = false;
}
}
//若标志还为真,这证明该数是质数
if (flag == true){
count++;
}
flag = true;
}
long end = System.currentTimeMillis();
System.out.println("所用时间"+(end - start)+"ms");
System.out.println("质数个数:"+count);
}
}
计算结果是:
看似计算结果用时不久,但这只是10万内的质数,若要求的是100万,用时就已经是非常久了,我等了好久也没算出来,所以要对该程序算法进行优化
优化一:
若变量i已经被除尽则无需再继续下去,应当及时跳出循环。
public class ZhiShu {
public static void main(String[] args) {
boolean flag = true;
int count = 0;//计算质数个数
long start = System.currentTimeMillis();
for (int i = 2;i<= 100000;i++){
for(int j = 2;j<i;j++){
if (i%j == 0){
flag = false;
//若变量i已经被除尽则无需再继续下去,应当及时跳出循环。
break;
}
}
//若标志还为真,这证明该数是质数
if (flag == true){
count++;
}
flag = true;
}
long end = System.currentTimeMillis();
System.out.println("所用时间"+(end - start)+"ms");
System.out.println("质数个数:"+count);
}
}
计算结果:
可以很明显的看到,经过算法优化后用时大大减少,但对于100万的数据依然需要非常久的时间,我也是没有等出来。
优化二:
这是就需要从变量i要除的数进行优化,我们都知道质数除了2之外都是奇数,这相当于减少了一半的计算量,但是这远远不够。这时我们就可以对i进行开根,这样计算量就会大大减少。
代码如下:
public class ZhiShu {
public static void main(String[] args) {
boolean flag = true;
int count = 0;//计算质数个数
long start = System.currentTimeMillis();
for (int i = 2;i<= 100000;i++){
//对变量i进行开根
for(int j = 2;j<Math.sqrt(i);j++){
if (i%j == 0){
flag = false;
//若变量i已经被除尽则无需再继续下去,应当及时跳出循环。
break;
}
}
//若标志还为真,这证明该数是质数
if (flag == true){
count++;
}
flag = true;
}
long end = System.currentTimeMillis();
System.out.println("所用时间"+(end - start)+"ms");
System.out.println("质数个数:"+count);
}
}
计算结果:
优化算法后的所用时间仅为13ms,这比不进行优化的时间减少了非常非常多。
使用continue对程序进行重构
public class ZhiShu {
public static void main(String[] args) {
int count = 0;//计算质数个数
long start = System.currentTimeMillis();
con:for (int i = 2;i<= 100000;i++){
//对变量i进行开根
for(int j = 2;j<Math.sqrt(i);j++){
if (i%j == 0){
continue con;
}
}
//能到执行到这的都是质数
count++;
}
long end = System.currentTimeMillis();
System.out.println("所用时间"+(end - start)+"ms");
System.out.println("质数个数:"+count);
}
}
计算结果:
使用优化后的算法对1000万以内的质数进行计算
代码如下:
public class ZhiShu {
public static void main(String[] args) {
int count = 0;//计算质数个数
long start = System.currentTimeMillis();
con:for (int i = 2;i<= 10000000;i++){
//对变量i进行开根
for(int j = 2;j<Math.sqrt(i);j++){
if (i%j == 0){
continue con;
}
}
//能到执行到这的都是质数
count++;
}
long end = System.currentTimeMillis();
System.out.println("所用时间"+(end - start)+"ms");
System.out.println("质数个数:"+count);
}
}
计算结果: