问题背景:最近在论坛上看见了关于素数的求解问题,所有收集了相关资料真理了几个常用的求素数的算法,希望对有兴趣的朋友提供方便
- (优化后的)基本算法
- 筛选法
- 6N+-1发(其实也是一种筛选法,只是构造的筛子更细了,提高了效率)
一、基本方法
- 方法描述:这种方法是通过n%i?=0,{i|2,3,...i*i=n}如果=0,那么n不是素数,结束本次循环
- 性能测试:num=50000,时间:80ms
- 总结:算法简单,但是效率其实还是挺搞的,因为在取模的时候,只要条件第一次不成立(n%m==0)那么就不再测试这个数,即跳出本次循环。算法的时间复杂度是很接近于O(n)的。
private static void prime(int num) {
long start = System.currentTimeMillis();
int m, n;
label: for (n = 2; n <= num; n++) {
for (m = 2; m * m <= n; m++) {
if (n % m == 0) {
continue label;
}
}
//太多了可能myeclipce中看不到打印结果,可以用num=100,测试
System.out.print(n + " ");
}
System.out.println();
System.out.print("时间:");
long end = System.currentTimeMillis();
System.out.println(end - start);
}
二、筛选法
算法描述:算法的思想是打表,先初始化一个数组{2,3,4,...,n}
我们以n=30为例
一、初始化表:2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
二、把第一个数(2)取出来,去掉所有可以被2整除的数。
2 3 5 7 9 11 13 15 17 19 21 23 25 27 29
三、取第二个数(3),去掉所有可以被 3整除的数。
2 3 5 7 11 13 17 19 23 25 29
四、取第三个数(5),因为4已经被去除了,再去掉所有可以被5整除的数。
2 3 5 7 11 13 17 19 23 29
五、取第四个数(7)7*7>30所以停止。
- 性能测试:num=50000,时间:24680ms
- 总结:此算法在理论上的效率其实是挺高的,但是实际在实现时是不可取的。
private static void prime3(int n) {
long start = System.currentTimeMillis();
List<Integer> list = new LinkedList<Integer>();
for (int i = 2; i <= n; i++) {
list.add(i);
}
for (int j = 0; j < list.size() && list.get(j) * list.get(j) <= n; j++) {
for (int k = 0; k < list.size(); k++) {
if ((list.get(k) != list.get(j))
&& list.get(k) % list.get(j) == 0) {
list.remove(k);
}
}
}
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i) + " ");
}
System.out.println();
System.out.print("时间:");
long end = System.currentTimeMillis();
System.out.println(end - start);
}
三、6N+-1法
- 算法描述:任何一个自然数,总可以表示成为如下的形式之一: 6N,6N+1,6N+2,6N+3,6N+4,6N+5 (N=0,1,2,…)
显然,当N≥1时,6N,6N+2,6N+3,6N+4都不是素数,只有形如6N+1和6N+5的自然数有可能是素数。所以,除了2和3之外,
所有的素数都可以表示成6N±1的形式(N为自然数)。 根据上述分析,我们可以构造另一面筛子,只对形如6
N±1的自然数进行筛选,这样就可以大大减少筛选的次数,从而进一步提高程序的运行效率和速度。
在程序上,我们可以用一个二重循环实现这一点,外循环i按3的倍数递增,内循环j为0-1的循环,则2(i+j)-1恰好就是形如6N±1的自然数。
- 性能测试:num=50000,时间:50ms
- 总结:此算法,其实也是一种筛选算法,只是筛子更细,能够将整数中大约2/3的数筛选出去。所以效率很高
private static void prime2(int num) {
long start = System.currentTimeMillis();
for (int n = 2; n <= 3; n++) {
System.out.print(n + " ");
}
label1: for (int n = 1;; n++) {
label2: for (int m = 0; m <= 1; m++) {
int tmp = 2 * (3 * n + m) - 1;
if (tmp > num)
break label1;
for (int k = 2; k * k <= tmp; k++)
if (tmp % k == 0)
if (m == 0)
continue label2;
else
continue label1;
System.out.print(tmp + " ");
}
}
System.out.println();
System.out.print("时间:");
long end = System.currentTimeMillis();
System.out.println(end - start);
}
分享到:
相关推荐
介绍了素数判定的几种算法。希望对大家能有用。谢谢
主要介绍了Java求质数的几种常用算法,结合实例形式分析了三种比较常见的求质数算法原理及相关实现技巧,需要的朋友可以参考下
ACM的素数判断,包括米勒拉宾伪素数判定,筛选法。
素数判断的几种方法代码实现及其复杂度分析.pdf
不同素数判定方法及C语言代码实现,分析各种方法的事件复杂度,适用于大数处理。
算法是解决特定问题或执行特定任务的一系列步骤或规则的有序集合。...这些是计算机科学中常见的算法类型,每种算法都有不同的应用场景和解决问题的方法。在实际编程中,选择合适的算法对于提高程序效率和性能至关重要。
。。。
。。。
本文实例讲述了javascript实现计算指定...算法来源:《Java求质数的几种常用算法》 javascript计算指定范围内的质数源代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.or
关于Java中素数的概念,及Java代码的写法,写了几种方法
素数判定问题是一个非常常见的问题,本文介绍了常用的几种判定方法。 2. 原始算法 素数的定义是,除了能被1和它本身整除而不能被其他任何数整除的数。根据素数定义 只需要用2到n-1去除n,如果都除不尽,则n是素数,...
RSA算法的纯Python实现,...RSA算法原理基于两个大质数的乘积很难因式分解,几种算法的优劣主要体现在质数判断、快速乘模运算、快速幂模运算等。如需实际应用建议使用大能们的实现:https://pypi.python.org/pypi/rsa/
图论(图论模型的建立,平面图,欧拉公式与五色定理,求强连通分量,求割点和桥,欧拉回路,AOV问题,AOE问题,最小生成树的三种算法,最短路的三种算法,标号法,差分约束系统,验证二分图,Konig定理,匈牙利算法...
关于筛素数大概有以下几种方法 1.遍历2–(n-1)判断有没有除一和其本身以外的因子。 2.加一点点技巧因为n=n的1/2次方乘以n的1/2次方,所以若n在2-(根号n)存在因子,则在根号n–n也存在因子,所以我们只需要遍历2...
RSA算法中模数和运算效率之间一直存在矛盾,目前一些认证机构已采用模数为 2048 ...在此基础上,本文选取了一种四素数RSA算法进行阐述和简单实现,这种算法巧妙地利用了中国剩余定理将传统的RSA算法的速度提升了几倍。
枚举 递归 回溯 贪心 动态规划 排序算法 LZW压缩 josephus 乘法表 积分 基数转换 矩阵问题举例 求解质数 圆周率的求法 改进的快速排序法 几种插入排序法 水仙花数 迷宫生成器 生命游戏
书中每一章都给出了一个算法、一种算法设计技术、一个应用领域或一个相关的主题。算法是用英语和一种“伪代码”来描述的,任何有一点程序设计经验的人都能看得懂。书中给出了230多幅图,说明各个算法的工作过程。...
个人积累的Java工具类扩展类,包括字符数组转字符串,质数判断,辗转相除法求最大公约数,对字符串的一些判断,几种常见的数组排序、插入、查找等,闰年判断 日期字符串解析等与日期有关的操作,随机字符串。...