用筛法求出100以内的全部素数

合集下载

埃塞法求素数

埃塞法求素数

埃塞法求素数什么是素数?素数是指大于1且只能被1和自身整除的整数。

例如,2、3、5、7、11等都是素数,而4、6、8、9等则不是素数。

素数在数论中具有重要的地位,它们的特殊性质使得它们在密码学、计算机科学等领域有广泛的应用。

埃塞法(筛法)是什么?埃塞法,又称筛法,是一种用于求解素数的算法。

它的基本思想是通过逐步筛除合数的方法,找出一定范围内的所有素数。

埃塞法的步骤1.首先,我们需要确定一个范围,假设为n。

2.创建一个长度为n+1的布尔数组,初始值都为True。

这个数组用来表示数字是否为素数,索引对应的数字为素数则对应的值为True,否则为False。

3.从2开始,将数组中索引为2的倍数的值设置为False,因为2的倍数肯定不是素数。

4.接下来,找到第一个为True的索引值,假设为p,这个值就是我们找到的第一个素数。

5.然后,将数组中索引为p的倍数的值设置为False,因为p的倍数肯定不是素数。

6.重复步骤4和5,直到找不到下一个为True的索引值。

7.最后,数组中为True的索引值就是范围内的所有素数。

一个简单的埃塞法求素数的实现(Python)下面是一个简单的Python代码示例,用于实现埃塞法求素数:def sieve_of_eratosthenes(n):primes = [True] * (n+1)primes[0] = primes[1] = Falsep = 2while p * p <= n:if primes[p]:for i in range(p * p, n+1, p):primes[i] = Falsep += 1result = []for i in range(2, n+1):if primes[i]:result.append(i)return resultn = int(input("请输入一个正整数n:"))primes = sieve_of_eratosthenes(n)print("范围内的素数有:", primes)示例说明在上述示例中,我们首先定义了一个名为sieve_of_eratosthenes的函数,它接受一个正整数n作为参数,返回范围内的所有素数。

C 使用筛选法求100以内的素数

C 使用筛选法求100以内的素数

C 使用筛选法求100以内的素数C++使用筛选法求100以内的素数,具体问题分析及其代码如下:【问题分析】我们可以把100个数看作是沙子和石子,素数是石子,非素数的是沙子,弄个筛子,将沙子筛掉,剩下的就是素数。

1至100这些自然数可以分为三类:(1) 单位数:仅有一个数1.(2) 素数:这个数大于1,且只有它本身和1这样两个正因数。

(3) 合数:除了1和他自身以外,还有其他的正因数。

【代码如下】/********************************************************/* 程序名:素数筛选/* 编程时间:2009年7月27日/* 主要功能:求素数*********************************************************/#include<iostream>using namespace std;//编译命令#include<math.h>const int MAX=100;//定义常量MAXint main()//主函数{int prime[MAX+100]={0};//定义变量并初始化int i,j,k=sqrt(MAX);for(i=2; i<=k; i++)//枚举筛数{if(prime[i]==0)//如果这个数没被筛,就看看{j=i*2;//将原数扩大二倍初始化给jdo{prime[j]=1;//将j筛掉j+=i; //再扩大一倍}while(j<=MAX);//直到最大}}for(i=2; i<=MAX; i++){if(prime[i]==0)//循环输出cout<<i<<" ";}cout<<endl;return 0;//主函数结束}【运行结果】。

素数快速筛法及公式

素数快速筛法及公式

素数快速筛法及公式素数快速筛法及公式梅生林安徽合肥2012.07.12摘要:在素数的研究中,总结出素数快速筛法及公式,在这个基础上扩展了素数的一些关系、性质。

关键词:素数快速筛法,素数通式,质数筛法公式1.引言素数(Prime Number)是指自然数中那些只能被1和本身整除的数,依次为2、3、5、7、11、13、17、19、23、29…。

前人已证明:素数有无限多个。

一直到现在人们判定、寻找素数的方法,还是古希腊的数学家艾拉托斯芬(Eratosthenes)提出过的筛式方法,简称“艾氏筛法”。

即在任意有限自然数N以内判定素数时,先把N一个不漏的写下来,然后划掉根号N()内所有素数的倍数,我们就能得到N以内的全部素数。

艾氏筛法判定素数的过程机械,也未能表示素数公式和一些性质。

关于寻找判定表示素数的方法公式,以前众多数学家进行了艰辛探索,也提出了很多关于素数的猜想和问题。

欧拉(Euler)就提出二项式公式n2-n+41能生成一部分素数的数型公式,直到现在,素数研究中仍然还有许多未解问题。

本文通过素数快速筛法及公式,总结出一些素数的新理论,使素数筛法及公式等都将是一次质变,将为素数研究抛砖引玉,也可能为数论增添上新的一页。

2.素数的快速筛法原理及公式当我们用艾氏筛法是要划掉每个合数,只2的倍数就差不多要划掉一半自然数,越往后面合数越多,而留下的素数越少。

我们能不能利用数学原理、公式去掉大部分合数呢?答案是肯定的。

2.1 当我们想去掉第一个素数2的倍数时,我们可能会想到用:2N+1 (N≥1)N为大于等于1的自然数,以下公式同上。

2.2 去掉2、3的倍数时,用2*3的倍数加上同为2、3互质的数:6N±12.3 去掉2、3、5的倍数时,用2*3*5的倍数加上同为2、3、5互质的数:30N±1,30N±7,30N±11,30N±13,2.4 去掉2、3、5、7的倍数时,同上的方法:210N±1,210N±11,210N±13,210N±17,210N±19,210N±23,210N±29,210N±31,210N±37,210N±41,210N±43,210N±47,210N±53,210N±59,210N±61,210N±67,210N±71,210N±73,210N±79,210N±83,210N±89,210N±97,210N±101,210N±103,2.5 去掉2、3、5、7、11的倍数时,同上的方法:2310N±1,2310N±13,2310N±17,2310N±19,……2310N±1139,2310N±1147,2310N±1151,2310N±1153,我们可以一直做下去,就会去掉从前面开始的素数倍数,划掉的合数比例将越来越少。

用筛法求100以内的素数

用筛法求100以内的素数

1. 用筛法求100以内的素数。

算法:先将1~100放置于一个一维数组中,然后依次判断每个数是否素数,若不是素数将该元素置0,最后输出不为0的数。

如何判断一个数是否素数?素数定义是只能被1和本身整除的数,设置除数n=2~a[i]-1特殊的两个数1、2,不需要判断定义变量:int a[100],i,n;输入数据:循环赋值,for(i=0;i<100;i++) a[i]=i+1;处理:双重循环,外层循环控制访问数组元素,内层循环控制除数的变化for(i=2;i<100;i++) for(n=2;n<=a[i]/2;n++) if(a[i]%n==0) a[i]=0;输出:for(i=0;i<100;i++)if(a[i]!=0) printf(“%3d”,a[i]);2. 编写一个程序,计算若干学生的某门功课的平均成绩、标准差,找出最高分和最低分。

算法:循环输入成绩,需要求和,然后求平均成绩;循环sqrt(求和(xi-aver)*(xi-aver))定义变量:float grade[N],max,min,aver,bzc,sum;int i;输入数据:for(i=0;i<N;i++) scanf(“%f”,&grade[i]);处理:sum=0; max=min=grade[0];for(i=0;i<N;i++) {sum=sum+grade[i];if(max<grade[i]) max=grade[i]; if(min>grade[i]) min=grade[i];}aver=sum/N;sum=0; for(i=0;i<N;i++) sum=sum+(grade[i]-aver)* (grade[i]-aver);bzc=sqrt(sum/N);输出结果3.编写一个程序,让计算机产生20个随机数,用选择法排序。

98 36 54 18 65 23 48 78 84 8for(i=0;i<N-1;i++){p=i;for(j=i+1;j<N;j++) if(a[p]>a[j]) p=j;if(p!=i) { t=a[p];a[p]=a[i];a[i]=t;}}设置一个变量p,去记住最小值的下标,4. 根据上题的内容1,编一程序在数组中查找一个数。

线性筛法求素数

线性筛法求素数

线性筛法求素数
线性筛法是一种求素数的算法,它是埃拉托斯特尼筛法的简化版本。

其主要思想是:首先用2去筛,然后用3去筛,接下来用5去筛,依次类推,将不大于根号n的所有素数的倍数剔除,最后剩下的就是素数。

1.先把2到n之间的数字从小到大排列好,设定一个变量p等于2;
2.把2这个数字标记为素数,并把它的倍数都标记为非素数;
3.将变量p加1,如果变量p的值不大于根号n,则重复步骤2,否则将p的值作为素数;
4.重复步骤3,直到p的值大于根号n;
5.此时得到了从2到根号n之间的所有素数。

第七章C语言谭浩强答案

第七章C语言谭浩强答案

7.1用筛法求100之内的素数。

解:所谓“筛法”指的是“Eratosthenes筛法”。

Eratosthenes是古希腊的著名数学家。

他采用的方法是:在一张纸上写下1~1000之间的全部整数,然后逐个判断它们是否素数,找出一个非素数就把它挖掉,最后剩下的就是素数。

1 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 2728 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 …具体做法如下:先将1挖掉(因为1不是素数)。

用2去除它后面的各个数,把能被2整除的数(如4,6,8…)挖掉,即把2的倍数挖掉。

用3去除它后面各数,把3的倍数挖掉。

分别用4,5…各数作为除数去除这些数以后的各数。

这个过程一直进行到在除数后面的数已全被挖掉为止。

例如在上表中1~50范围内的素数,要一直进行到除数为47为止。

事实上,这一过程可以简化。

如果需要找1~n数)即可。

例如对1~50,只需进行到将7上面的算法可表示为:挖去1;用刚才被挖去的数的下一个数p去除p后面的各数,把p的倍数挖掉;检查p n=1000,则检查p<31否),如果是,则返回(2)继续执行,否则就结束;纸上剩下的就是素数。

解题的基本思路有了,但要变成计算机的操作,还要作进一步的分析。

如怎样判断一个数是否已被“挖掉”,怎样找出某一个数p的倍数,怎样打印出未被挖掉的数。

可以设一个数组a,a[1]到a[100]的值分别是1,2,3,…100。

然后用上述方法将非素数“挖去”。

如果一个数被认为是非素数,就将它的值变为零,最后将不为零的数组元素输出,就是所求的素数表。

程序如下:#include <math.h>main ( ){int i,j,n,a[101];for (i=1;i<=100;i++)a[i] =i;for (i=2;i<sqrt(100);i++)for (j=i+1;j<=100;j++){if (a[i]!=0 && a[j]!=0)if (a[j]%a[i]==0)a[j]=0; } /*非素数,赋值为0,“挖掉”*/printf(“\n”);for (i=2,n=0;i<=100;i++){ if (a[i]!=0){printf(“%5d”,a[i]);n++; }if (n==10) /*此处if 语句的作用是在输出10个数后换行*/{ printf (“\n”);n=0; }}}运行结果:2 3 5 7 11 13 17 19 23 29 31 37 41 4347 53 59 61 67 71 73 79 83 89 977.2用选择法对10个整数排序(从小到大)。

埃氏筛法求素数

埃氏筛法求素数

埃氏筛法求素数素数一直以来都是数学家们所钟情的主题,古希腊数学家埃及里斯(Eratosthenes)在公元前三世纪就发明了一种基于排除法的算法埃氏筛法,它可以用来有效地求出指定数字范围内的素数。

其基本原理是,从2开始,把2的倍数剔除掉,然后再把3的倍数剔除掉,最后再把4的倍数剔除掉,以此类推,如此循环地排除,剩下来的数字就是指定范围内的素数。

埃氏筛法的实现,一般采用一维布尔数组的形式,其元素的个数为指定数字范围内的数字数目,元素值初始均为真,每次排除一个指定数字的倍数时,即将该数字的倍数设为假,这样可以较简单地实现埃氏筛法,并且排除一个数字的倍数可以利用已排除的数字的倍数的倍数进行排除,即可以多次排除,从而大大地提高求素数的效率。

实际应用中,在求特定数字范围内的素数时,可以利用埃氏筛法进行求解,但是,当数字范围较大时,这种方式会有一定的效率问题,因为必须要对所有数字进行判断。

从历史上看,埃及里斯提出了埃氏筛法以求素数,这种排除法算法虽然比较直接,但还是具有很大的时间效率,所以,后来中国古代数学家张丘建更进一步,提出了更加高效的“秦九韶算法”,而此算法是后来的素数求解算法(如Sieve of Atkin算法和Sieve of Sundaram算法)的基础。

在具体实现上,埃氏筛法的实现可以适用各种编程语言,如C、C++、Java等。

下面给出一段C语言代码,用来实现埃氏筛法:#include <stdio.h>//求1000以内的素数#define N 1000int main( ){int i, j, a[N];//初始化数组for (i = 2; i < N; i++)a[i] = 1;//埃氏筛法for (i = 2; i < N; i++){if (a[i]){for (j = i; j <= N / i; j++) {a[i * j] = 0;}}}//输出素数for (i = 2; i < N; i++){if (a[i])printf(%d i);}printf(return 0;}总之,埃氏筛法是一种有效的素数求解方法,它具有比较高的效率,可以应用于大规模数字范围内的素数求解。

c++用筛法求100之内素数。

c++用筛法求100之内素数。

c++⽤筛法求100之内素数。

1、⽤筛法求100之内素数。

相关知识:⽤筛法求素数的基本思想是:把从1开始的、某⼀范围内的正整数从⼩到⼤顺序排列, 1不是素数,⾸先把它筛掉。

剩下的数中选择最⼩的数是素数,然后去掉它的倍数。

依次类推,直到筛⼦为空时结束。

如有:1234567891011121314151617181920212223242526272829301不是素数,去掉。

剩下的数中2最⼩,是素数,去掉2的倍数,余下的数是:357911131517192123252729剩下的数中3最⼩,是素数,去掉3的倍数,如此下去直到所有的数都被筛完编程要求:根据提⽰,在右侧编辑器补充代码,输出100以内所有素数。

预期输出:2357111317192329313741434753596167717379838997程序源码:#include <iostream>#include <iomanip>using namespace std;#include <math.h>int main(){// 请在此添加代码/********** Begin *********/int count=0,susu=1;for(int i=2;i<100;i++){for(int j=2;j<=i/2;j++) //只需要循环到原本数的⼀半即可{if(i%j==0){susu=0;break;}}if(susu){printf("%5d ",i);count++;if(count==10) //输出10个数就换⾏{count=0;printf("\n");}}susu=1;}/********** End **********/return0;}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

例6、用筛法求出100以内的全部素数,并按每行五个数显示。

【问题分析】⑴把2到100的自然数放入a[2]到a[100]中(所放入的数与下标号相同);⑵在数组元素中,以下标为序,按顺序找到未曾找过的最小素数minp,和它的位置p(即下标号);⑶从p+1开始,把凡是能被minp整除的各元素值从a数组中划去(筛掉),也就是给该元素值置0;⑷让p=p+1,重复执行第②、③步骤,直到minp>Trunc(sqrt(N)) 为止;⑸打印输出a数组中留下来、未被筛掉的各元素值,并按每行五个数显示。

用筛法求素数的过程示意如下(图中用下划线作删去标志):① 2 3 4 5 6 7 8 9 10 11 12 13 14 15…98 99 100 {置数}② 2 3 4 5 6 7 8 9 10 11 12 13 14 15…98 99 100 {筛去被2整除的数}③ 2 3 4 5 6 7 8 9 10 11 12 13 14 15…98 99 100 {筛去被3整除的数}……2 3 4 5 6 7 8 9 10 11 12 13 14 15…98 99 100 {筛去被整除的数}Program Exam53;const N=100;type xx=1 .. N; {自定义子界类型xx(类型名)}Var a: array[xx] of boolean; i,j: integer;BeginFillchar(a,sizeof(a),true);a[1] := False;for i:=2 to Trunc(sqrt(N)) doif a[I] thenfor j := 2 to N div I doa[I*j]:= False;t:=0;for i:=2 to N doif a[i] thenBeginwrite(a[ i ]:5); inc(t);if t mod 5=0 then writelnend;End.【例3】输入十个正整数,把这十个数按由大到小的顺序排列(将数据按一定顺序排列称为排序,排序的算法有很多,其中选择排序中的“简单选择排序”是一种较简单的方法)分析:要把十个数按从大到小顺序排列,则排完后,第一个数最大,第二个数次大,……;因此,我们第一步可将第一个数与其后的各个数依次比较,若发现,比它大的,则与之交换,比较结束后,则第一个数已是最大的数。

同理,第二步,将第二个数与其后各个数再依次比较,又可得出次大的数。

如此方法进行比较,最后一次,将第九个数与第十个数比较,以决定次小的数。

于是十个数的顺序排列结束。

例如下面对5个进行排序,这个五个数分别为829105。

按选择排序方法,过程如下:初始数据:82910 5第一轮排序:82910 592810 510289 510289 5第二轮排序:10829 510928 510928 5第三轮排序:10982 510982 5第四轮排序:10985 2对于十个数,则排序要进行9次。

源程序如下:program ex5_2;vara:array[1..10]of integer;i,j,t:integer;beginwriteln('Input 10 integers:');for i:=1 to 10 do read(a[i]);{读入10个初始数据}readln;for i:=1 to 9 do{进行9次排序}beginfor j:=i+1 to 10 do{将第i个数与其后所有数比较}if a[i]<a[j] then {若有比a[i]大,则与之交换}begint:=a[i];a[i]:=a[j];a[j]:=t;end;write(a[i]:5);end;end.例5、编程输入十个正整数,然后自动按从大到小的顺序输出。

(冒泡排序)【问题分析】①用循环把十个数输入到A数组中;②从A[1]到A[10],相邻的两个数两两相比较,即:A[1]与A[2]比,A[2]与A[3]比,……A[9]与A[10]比。

只需知道两个数中的前面那元素的标号,就能进行与后一个序号元素(相邻数)比较,可写成通用形式A[ i ]与A[ i +1]比较,那么,比较的次数又可用1~( n - i )循环进行控制(即循环次数与两两相比较时前面那个元素序号有关) ;③在每次的比较中,若较大的数在后面,就把前后两个对换,把较大的数调到前面,否则不需调换位置。

下面例举5个数来说明两两相比较和交换位置的具体情形:5 6 4 3 7 5和6比较,交换位置,排成下行的顺序;6 5 4 37 5和4比较,不交换,维持同样的顺序;6 5 4 37 4和3比较,不交换,顺序不变6 5 4 37 3和7比较,交换位置,排成下行的顺序;6 5 47 3 经过(1~(5-1))次比较后,将3调到了末尾。

经过第一轮的1~(N-1)次比较,就能把十个数中的最小数调到最末尾位置,第二轮比较1~(N-2)次进行同样处理,又把这一轮所比较的“最小数”调到所比较范围的“最末尾”位置;……;每进行一轮两两比较后,其下一轮的比较范围就减少一个。

最后一轮仅有一次比较。

在比较过程中,每次都有一个“最小数”往下“掉”,用这种方法排列顺序,常被称之为“冒泡法”排序。

Program Exam52;const N=10;Var a: array[1..N] of integer; {定义数组}i,j: integer;procedure Swap(Var x,y: integer); {交换两数位置的过程}Var t:integer;begint:=x; x:=y; y:=tend;Beginfor i:=1 to N do {输入十个数}beginReadln(a[ i ])end;for j:=1 to N-1 do {冒泡法排序}for i:=1 to N-j do {两两相比较}if a[ i ] < a[i+1] then swap(a[ i ], a[i+1]); {比较与交换}for i:=1 to N do {输出排序后的十个数}write(a[ i ]:6);Readlnend.例:读入5个学生的学号和成绩,计算他们的平均分,若比平均分高10分的等第为A,若比平均分高小于10分的等地为B,若低于平均分,则等第为C,输出他们的成绩和等第。

program sample7d1(input,output);const n=5;typeno=array[1..n] of integer;s=array[1..n]of real;vari:integer;k:real;num:no;score:s;begink:=0;for i:=1 to n dobeginreadln(num[i],score[i]);k:=k+score[i];end;k:=k/n;for i:=1 to n dobeginwrite(num[i],score[i]);if (score[i]-k)>=10 then writeln('A')else if((score[i]-k)<10)and((score[i]-k)>0) then writeln('B')else writeln('C');end;end.3.输入一串小写字母(以"."为结束标志),统计出每个字母在该字符串中出现的次数(若某字母不出现,则不要输出) ,例:输入:aaaabbbccc.输出:a:4b:3c:34.输入一个不大于32767的正整数N,将它转换成一个二进制数,例如:输入:100输出:1100100*5.输入一个由10个整数组成的序列,其中序列中任意连续三个整数都互不相同,求该序列中所有递增或递减子序列的个数,例如:输入:1108593267 4输出:6对应的递增或递减子序列为:11010855993 22677 4*6.输入N个数,将这N个数按从小到大的顺序显示出来;**7.猴子选大王:有N只猴子围成一圈,每只猴子各一个从1到N中的依次编号,打算从中选出一个大王;经过协商,决定出选大王的规则:从第一个开始循环报数,数到M的猴子出圈,最后剩下来的就是大王。

要求:从键盘输入N、M,编程计算哪一个编号的猴子成为大王样例:输入:73输出:4输入:52输出:3待解:输入:99915输出:?**8.编程求出100!的末尾有多少个连续的0;(100!=1×2×3×4×……×99×100)1、编程将一个十进制数转换成二进制数、八进制数或十六进制数。

例如输入:73 10 2输出:(73)10=(1001001)2var i,j,n,m:longint;b:array [1..30] of integer;beginwrite('Input n,m:'); readln(n,m);write(n,'=('); i:=0;while n<>0 dobegin ?i:=i+1;b[i]:=n mod m; n:=n div mend;for j:=i downto 1 docase b[j] of10:write('A');11:write('B');12:write('C');13:write('D');14:write('E');15:write('F');??else write(b[j]);end;write(')',m);end. 2、设计一个抽签的程序。

var a:array[1..20] of integer;r,i,t:integer;beginrandomize;for i:=1 to 20 do a[i]:=i;for i:=20 downto 1 dobeginr:=random(20)+1;t:=a[i]; a[i]:=a[r]; a[r]:=tend;for i:=1 to 20 do write(a[i]:5);writelnend. 3、设有已按从小到大顺序排列的数组A、B,将他们合并成一个从小到大顺序排列的数组C。

4、给定一串整数数列,求出所有的递增和递减子序列的数目。

如7,2,6,9,8,3,5,2可分为(7,2)、(2,6,9)、(9,8,3)、(3,5)、(5,2,1)5个子序列。

答案是5。

我们称2,9,3,5为转折元素。

var a:array[1..20] of integer;i,c:integer;beginread(n);for i:=1 to n do read(a[i]);i:=1; c:=1;repeatif a[i]>a[i+1]then beginrepeati:=i+1until (i>=n-1) or (a[i]<=a[i+1]);if a[i]<a[i+1] then c:=c+1;end;if a[i]<a[i+1]?then beginrepeati:=i+1until (i>=n-1) or (a[i]>=a[i+1]);if a[i]>a[i+1] then c:=c+1;end;?until i>=n-1;?writeln('count:',c);end. 5、有一群猴子共N只,要选大王。

相关文档
最新文档