素数搜索
来源:互联网 发布:多核优化软件 编辑:程序博客网 时间:2024/05/16 07:27
- 伽利略:“ 素数是上帝用来描写宇宙的文字 。”
素数,又称为质数,是不能被1与其本身以外的其他整数整除的整数。如2、3、5、7、11、13、17是前几个素数,其中 2为唯一的偶素数;
与此相对应,一个整数如果能被除1与其本身以外的整数整除,该整数称为合数或复合数。例如,15能被除1与15以外的整数3、5整除,15是一个合数;
特别地,数 1既不是素数,也不是合数;
作为一类特殊的整数,素数是数论中探讨最多的也是难度最大的一类整数,其中有些问题是许多著名数学家提出并研究过的经典问题;
试商判别法
试应用试商判别法求出指定区间上的所有素数,并统计该区间上素数的个数;
1.说明:
试商判别法是依据素数的定义来实施的;
应用试商,法来探求奇数i(只有唯一的偶素数2,不作试商判别)是不是素数,用奇数j(取3,5,…,sqrt(i))去试商,若存在某个j能整除i,说明i能被1与本身以外的整数j整除,i不是素数,若上述范围内的所有奇数j都不能整除i,则i为素数;
有些程序把试商奇数j的取值上限定为 i/2 或 i-1 也是可行的,但并不是可取的,这样无疑会增加了试商的无效循环,理论上说,如果i存在一个大于sqrt(i)且小于i的因数,则必存在一个与之对应的小于sqrt(i)且大于1的因数,因而从判别功能来说,取到sqrt(i)已足够;
判别j整除i常用表达式 i%j=0 实现;
2.程序设计:
#include<stdio.h>#include<math.h>int main(){ long c,d,i,j,n,t; printf("请输入区间上下限c,d(c>2):"); scanf("%ld,%ld",&c,&d); printf("求区间[%ld,%ld]上的素数:\n",c,d); if(c%2==0) c=c+1; n=0; for(i=c;i<=d;i+=2) { for(t=0,j=3;j<=sqrt(i);j+=2) if(i%j==0) /*实施试商*/ { t=1; break; } if(t==0) /*标志量t=0时i为素数*/ { printf("%ld ",i); n++; /*统计素数的个数*/ if(n%5==0) printf("\n"); } } printf("\n共%ld个素数。",n);}
3.程序运行示例及其注意事项:
请输入区间上下限c,d(c>2):2000,2100求区间[2000,2100]上的素数:2003 2011 2017 2027 20292039 2053 2063 2069 20812083 2087 2089 2099共14个素数。
厄拉多塞 筛法
求素数的筛法 是公元前三世纪的 厄拉多塞(Eratosthenes)提出来的:
- 对于一个大整数x,只要知道不超过 sqrt(x) 的所有素数p,划去所有p的倍数2p,3p,…,剩下的整数就是不超过x的全部素数;
应用筛法求素数,为了方便实施“划去”操作,应设置数组。每一数组元素对应一个待判别的奇数,并赋初值0,如果该奇数为p的倍数则应划去,对应元素加一个划去标记,通常给该元素赋值-1,最后,打印元素值不是-1(即没有划去)的元素对应的奇数即所求的素数;
在实际应用筛法的过程中,p通常不限于取不超过 sqrt(x) 的素数,而是适当放宽取不超过 sqrt(x) 的奇数(从3开始)。这样做尽管多了一些重复划去操作,但程序实现要简便些;
1.说明:
设置a数组存储区间中的所有奇数,凡“划去”的数组元素赋值“-1”;
在指定区间 [c,d] (约定c为奇数)上所有的奇数表示为 j=c+2*k(k=0,1,…,e,这里 e=(d-c)/2 )。于是k=(j-c)/2是奇数j在数组中的序号(下标)。如果j为奇数的倍数时,对应数组元素作“划去”标记,即 a[(j-c)/2]=-1 ;
根据c与奇数i确定g=2 * int(c/(2*i))+1,使得gi接近区间下限c,从而使划去的gi,(g+2)i,…,在 [c,d] 中,减少无效操作,以提高对广大区间的筛选效率;
最后,凡数组元素 a[k]!=-1,对应的奇数j=c+2*k就为素数;
2.程序设计:
#include<stdio.h>#include<math.h>int main(){ long c,d,e,g,i,j,k,n; static long int a[80000]; printf("请输入区间上下限c,d(c>2):"); scanf("%ld,%ld",&c,&d); printf("求区间[%ld,%ld]上的素数:\n",c,d); if(c%2==0) c=c+1; e=(d-c)/2; i=1; while(i<=sqrt(d)) /*在[c,d]中筛选素数*/ { i=i+2; g=2*int(c/(2*i))+1; if(g*i>d) continue; if(g==1) g=3; j=j*g; while(j<=d) { if(j>=c) a[(j-c)/2]=-1; j=j+2*i; } } for(n=0,k=0;k<=e;k++) if(a[k]!=-1) /*输出所得素数*/ { n++; printf("%ld ",c+2*k); if(n%5==0) printf("\n"); } printf("\n共%ld个素数。\n",n);}
3.程序运行示例及其注意事项:
请输入区间上下限c,d(c>2):1671800,1672000求区间[1671800,1672000]上的素数:1671801 1671807 1671813 1671825 16718351671853 1671855 1671867 1671883 16718911671903 1671909 1671925 1671933 16719391671945 1671967共17个素数。
注意:
试商法较为直观,设计容易实现,因此常为程序设计爱好者所采用;
筛法在较大区间的搜索与较大整数的判别上效率更高一些,但设计上较难把握;
- 素数搜索
- 素数环 搜索
- 素数环(搜索)
- 艾氏筛法搜索素数
- 【USACO4.3.2】素数方阵 搜索搜索!
- 1016素数环的搜索
- bzoj1053 反素数ant 搜索
- 素数环问题,深度搜索
- POJ 2034 反素数,素数筛选,DFS暴力搜索
- nyist 488 素数环(搜索+回溯)
- NYOJ-488(搜索)-题目-----------------------------素数环
- hdu素数环(搜索入门题)
- BZOJ 1053 - 反素数(搜索)
- HDU 1016素数环(深度搜索)
- [闲聊]搜索素数的一个方法
- 搜索——素数环(hdu1016)
- [BZOJ 1053][HAOI2007]反素数ant:搜索
- BZOJ 4803: 逆欧拉函数 素数测试 搜索
- 学习笔记--mysql索引(一) 索引使用,index,key,primary key, unique
- Swift中的String
- 欧拉计划 7
- Ionic navigation
- WEB安全性测试之 -认证与授权、Session与Cookie、DDOS拒绝服务攻击
- 素数搜索
- trust zone之我见
- 浙江大学ZOJ 1005题 解题报告
- JAVAScript简单动画~移动方块~setInterval()~碰到边缘弹回
- 理解设计模式之代理模式
- Python 对文件内容迭代 按行处理
- 癌细胞形态学分析
- JavaSript模块化
- 关键路径 + 拓扑排序