质数(素数):只能被1和其本身整除的数字(其中1和0不属于质数)

接下来我们用多种方法求1000以内(包含1000)的质数数量,并且统计每种方法的循环次数
(如果只想知道速度快的方法可以直接看方法五)

方法一:

循环遍历所有情况

int count1 = 0;//质数个数
int count2 = 0;//循环次数
for(int i=2;i<=1000;i++) {int flag = 0;//用作标记,如果是质数就为0,不是质数就为1for(int j=2;j<i;j++){count1++;if(i % j == 0 ){flag = 1;//不是质数,改为1}}if(flag == 0){count2++;}
}
System.out.println(count1);
System.out.println(count2);

此时总循环次数为498501次
质数个数有168个

方法二

改进点: 当一个数第一次被比自己小的数(不包含1)整除成功后,我们就可以立刻判断出这个数不是质数,所以我们使用break跳出循环,结束对这个数接下来的判断

int count1 = 0;//质数个数
int count2 = 0;//循环次数
for(int i=2;i<=1000;i++) {int flag = 0;//用作标记,如果是质数就为0,不是质数就为1for(int j=2;j<i;j++){count1++;if(i % j == 0 ){flag = 1;//不是质数,改为1break;//既然已经知道这个数不是质数,那么就可以结束对这个数字的判断}}if(flag == 0){count2++;}
}
System.out.println(count1);
System.out.println(count2);

此时总循环次数为78022次
质数个数有168个

方法三

改进点: 如果存在数字1能被数字2整除,那么一定存在这样一个小于等于数字1算术平方根的数字2(数学定理),所以一个数字在2~本身算术平方根这个数字区间内没有遇到能够被整除的数字,那么这个数就不是质数
  简单解释一下:因数都是成对出现的。比如,100的因数有:1和100,2和50,4和25,5和20,10和10。看出来没有?成对的因数,其中一个必然小于等于100的开平方,另一个大于等于100的开平方。

注释掉的部分可以进一步提高计算速度,但提高不是非常大

int count1 = 0;//质数个数
int count2 = 0;//循环次数
for(int i=2;i<=1000;i++) {int flag = 0;//用作标记,如果是质数就为0,不是质数就为1//if(Math.sqrt(i)!=(int)Math.sqrt(i)){for (int j = 2; j <= Math.sqrt(i); j++) {//j改为小于i的平方根count2++;if (i % j == 0) {flag = 1;//不是质数,改为1break;//既然已经知道这个数不是质数,那么就可以结束对这个数字的判断}}//}else {//    count2++;//}if (flag == 0) {count1++;}
}
System.out.println(count1);
System.out.println(count2);

此时总循环次数为5288次
质数个数有168个

方法四

改进点: 如果数字1取余数字2不等于0,那么数字一取余数字2的倍数一定也不为0。
例如:7%2!=0那么我们没必要再去算7%4和7%6,因为4=22,6=32
所以,我们只需要判断一个数是否能被小于他的质数除尽即可
在这里我们将已经算出来为的质数存到一个数组中,后续的%只需对该数组中小于这个数本身平方根的数字进行

int count1 = 0;//质数个数
int count2 = 0;//循环次数
int re[] =new int[500];//定义一个数组,用于储存质数
re[0] = 2;
int k = 0;
for(int i=2;i<=1000;i++) {int flag = 0;//用作标记,如果是质数就为0,不是质数就为1for(int j=0;j<=k;j++){count2++;if(re[j]>Math.sqrt(i)){//只去小于等于该数字本身平方根的数字break;}if(i % re[j] == 0 ){//只对质数取余flag = 1;//不是质数,改为1break;//既然已经知道这个数不是质数,那么就可以结束对这个数字的判断}}if (flag == 0) {re[++k] = i;count1++;}
}
System.out.println(count1);
System.out.println(count2);

此时总循环次数为3467次
质数个数有168个

方法五

boolean prime[] = new boolean[1001];
int count1 = 0;//质数个数
int count2 = 0;//循环次数
for(int i=2;i<1000;i++){prime[i] = true;
}
for(int i=2;i<=1000;i++){if(prime[i]){for(int j=i+i;j<1000;j+=i){count2++;prime[j] = false;}}
}
for(int i=0;i<=1000;i++){if(prime[i] == true){count1++;}
}
System.out.println(count1);
System.out.println(count2);

此时总循环次数为1956次
质数个数有168个

讲解: 利用了筛法,首先,2是公认最小的质数,所以,先把所有2的倍数去掉;然后剩下的那些大于2的数里面,最小的是3,所以3也是质数;然后把所有3的倍数都去掉,剩下的那些大于3的数里面,最小的是5,所以5也是质数……
  上述过程不断重复,就可以把某个范围内的合数全都除去(就像被筛子筛掉一样),剩下的就是质数了。维基百科上有一张很形象的动画,能直观地体现出筛法的工作过程。

问题延伸

现在是让你求1000以内的素数,我们可以写死让i<=1000,但如果题目改为让你按从小到大的顺序,输出1000个质数该怎么办呢?第1000个质数的范围在哪里呢?
如果我们使用上面的方法四可以这样写

int count1 = 0;//质数个数
int count2 = 0;//循环次数
int re[] =new int[1001];//定义一个数组,用于储存质数
re[0] = 2;
int k = 0;
for(int i=2;;i++) {if(count1==1000){break;}int flag = 0;//用作标记,如果是质数就为0,不是质数就为1for(int j=0;j<=k;j++){count2++;if(re[j]>Math.sqrt(i)){//只去小于等于该数字本身平方根的数字break;}if(i % re[j] == 0 ){//只对质数取余flag = 1;//不是质数,改为1break;//既然已经知道这个数不是质数,那么就可以结束对这个数字的判断}}if (flag == 0) {re[++k] = i;count1++;}
}
System.out.println(count1);
System.out.println(count2);

但是我们知道方法四方法五要慢很多,但方法五中我们是提前定好了boolean prime[] = new boolean[1001];,第一千个质数我们应该将prime[]的大小定位多少呢?

这就涉及到了我们的数学知识, 数学家找到了一些公式,用来估计某个范围内的素数,大概有几个。在这些公式中,最简洁的就是 x/ln(x),公式中的 ln 表示自然对数(估计很多同学已经忘了啥叫自然对数)。假设要估计1,000,000以内有多少质数,用该公式算出是72,382个,而实际有78,498个,误差约8个百分点。该公式的特点是:估算的范围越大,偏差率越小。
  有了素数定理,就可以根据要打印的质数个数,反推出这些质数分布在多大的范围内。因为这个质数分布公式有一定的误差(通常小于15%)。为了保险起见,把反推出的素数分布范围再稍微扩大15%,应该就足够了。

空间优化

看到这你因为这已经是最优的解法了吗?不,现在我们只优化了时间,还没有优化空间。
有些程序猿会想出按位(bit)存储的思路。
  以Java为例。一个boolean占用4字节内存(boolean类型占了单独使用是4个字节,在数组中又是1个字节)。而1个字节有8个比特,每个比特可以表示0或1。所以,当你使用按位存储的方式,一个字节可以拿来当8个布尔型使用。所以,构造一个定长的byte数组,数组的每个byte存储8个布尔值。空间性能相比直接定义boolean,提高8倍(对于Java而言)。

最后总结

关于代码优化这件事,我认为没有最优,只有更优,科技永远不会停下前进的脚步

努力吧,少年!

求质数(素数)算法,及算法优化相关推荐

  1. python实现求质数(素数)

    python实现求质数(素数) 素数(质数):我们把公约数只有1和它本身的数字称为素数又称为质数,具体使用python的求法如下: num = [] # 定义一个空列表用来接收找到的符合条件的数字 f ...

  2. 判断素数或者求出素数的基本算法 《挑战程序设计竞赛》

    2018-2-28 首先我们得明确一个概念,那就是什么是素数,据我的了解,素数就是除了1和它本身之外,不存在其他的因数的数. 1.素性测试 判断给定的数n是否是素数 这应该是最简单的了,直接从2至n, ...

  3. Java 洛谷 求质数(素数)、合数、因数、最大公约数、最小公倍数

    什么是因数? "因数是指整数a除以整数b(b≠0) 的商正好是整数而没有余数,我们就说b是a的因数.而小学数学定义 :假如a*b=c(a.b.c都是整数),那么我们称a和b就是c的因数.&q ...

  4. 求质数(素数)的方法

    质数是数学重要的一环,所谓质数,就是除了1和它本身外不存在任何因子的数.以下整理了一下c语言中质数的求法. 问题:输入一个正整数n(n>=2),求不大于n的全部质数 方法一:循环法 思路:判断一 ...

  5. java中求质数(素数)的问题

    1.什么是质数? 定义:质数又称为素数,一个大于1的自然数,除了1和它自身之外,不能被其他任何自然数整除的数叫质数. 2.请输出1~100之间的所有的质数? 3.思路: <1>外层循环作为 ...

  6. MySQL素数怎么,求质数(素数)的方法

    质数是数学重要的一环,所谓质数,就是除了1和它本身外不存在任何因子的数.以下整理了一下c语言中质数的求法. 问题:输入一个正整数n(n>=2),求不大于n的全部质数 方法一:循环法 思路:判断一 ...

  7. 质数(素数)的几种求法

    质数就是只能被1和它本身整除的数.求质数在程序设计和算法中很常见,尤其是在密码学中经常用到质数.最通常的想法就是依据定义来求质数 如求100以内的质数,我们会写出如下的算法: int prime_1( ...

  8. 判断 一个数 是不是 质数 / 素数

    判断 一个数 是不是 质数 / 素数 [面试必备 100题 系列 ]- 001 - 判断 一个数 是不是 质数 / 素数 一.命题分析: 质数 又称 素数.指整数在一个大于1的 自然数 中,除了1和此 ...

  9. c语言生成两位随机素数算法,[算法]费马小定理求质数的算法之Miller-Rabin算法,C语言实现 | 李大仁博客...

    今天讲点比较高级的算法,目的也很简单,求质数,但是应用一种新的算法Miller-Rabin算法,这是一种利用了概率和费马小定理的算法设计,有点玄乎吧,其实本人也是刚接触这种算法,这是一种纯数学的解法, ...

  10. c语言筛选法_「干货」C语言经典算法筛选法求质数,极少数人用过的素数求解法...

    小编是一个有着6年工作经验的工程师,关于C++编程,自己有做材料的整合,一个完整的C++编程学习路线,学习资料和工具,能够进我的群10048,-83029收取,免费送给大家,希望你也能凭着自己的努力, ...

最新文章

  1. 如果乔布斯还在,今天他65岁了
  2. Invalid byte tag in constant pool: 19 与 javax/el/ELManager问题解决
  3. tracert 路由跟踪程序
  4. zabbix如何添加图表显示内容_Zabbix图表出现中文乱码解决方案
  5. 错误的日志可能会导致疯狂;好日志可能会成为魔杖
  6. RFIC4463_F3CD
  7. 各种好用的开源库。快点进来,包你喜欢~^_^
  8. 苹果mac视频音频格式转换软件:Permute
  9. Angular——Angular 教程
  10. 在线教学试卷讲评利器——屏幕画笔
  11. 北京邮电大学计算机院专业录取分数线,2017年北京邮电大学计算机科学与技术专业在北京录取分数线...
  12. 如何将产品发布到App Store上?
  13. Onedrive 1T|5T 网盘获取
  14. python多个if怎么优化_利用策略模式优化过多 if else 代码
  15. 2020年中国废旧纺织品回收行业市场现状分析,高值化再生技术持续推进「图」
  16. 当年,我被智联招聘坑惨了!
  17. Ubuntu 提示boot空间不足的解决办法
  18. 【Prometheus】Metric类型的理解及运用
  19. JDE(j的拼音格式怎么写)
  20. Nuendo 4 v4.3 WiN 音乐制作软件中文精简版下载

热门文章

  1. 电脑屏幕亮度怎么调?四种自由调节亮度方式
  2. 台积电5nm光刻技术
  3. 2073:【例2.16 】三角形面积
  4. pytorch笔记(四)nn.Conv1d、nn.Conv2d、nn.Conv3d
  5. ubuntu16.04解决tensorflow提示未编译使用SSE3、SSE4.1、SSE4.2、AVX、AVX2、FMA的问题【转】...
  6. NIST随机数测试软件下载,安装、和使用,分析方法最新版(19年4月)
  7. [LayoutConstraints] Unable to simultaneously satisfy constraints.
  8. 自由市场经济、社会主义和大数据
  9. 王岚老师计算机,平凡中演绎精彩——优秀教师王岚
  10. 2021年各大互联网大厂年终奖一览表~新年干劲十足