c语言求素数伴侣

c语言求素数伴侣
c语言求素数伴侣

#include

int n[100],m[50],count=0;//n用于盛放输入的数,m用于记录每种组合的素数伴侣,count用于记录数组小标

int i,s;////记录输入的数的个数

/////判断一个数是否为素数

int issu(int a)

{

int i;

for(i=2;i<=a/2;i++)

if(a%i==0)

return 0;

return 1;

}

void f()

{

int j,k,l,temp[100],temp1=0;

int p=0;

i=s;

////////初始化数组temp[100]

for(j=0;j

temp[j]=n[j];

//////求某中组合的素数伴侣的个数

for(j=0;j

for(k=j+1;k

{

p=temp[j]+temp[k];

if(issu(p))///如果两个数的和为素数

{

m[count]++;///对应的数组值加1(记录每中组合数的素数伴侣个数)

for(l=k;l

temp[l]=temp[l+1];///把满足条件的一对素数的后一个数的后面的数向前移一位

i--;///数组长度减去1

break;//跳出本次循环

}

else

continue;

}

count++;//数组下标加1

////把数组的第一个数移动到最后一位。

temp1=n[0];

for(j=0;j

n[j]=n[j+1];

n[s-1]=temp1;

}

void main()

{

int j,k;

int temp;

scanf("%d",&s);

for(j=0;j

scanf("%d,",&n[j]);

for(j=0;j

f();

for(j=0;j<50;j++)////对记录每种组合素数伴侣个数的数组进行排序(从大到小)for(k=j+1;k<50;k++)

if(m[j]

{

temp=m[j];

m[j]=m[k];

m[k]=temp;

}

printf("%d\n",m[0]);///输出其中最大的一个

}

我发现了筛法的计算公式(最后稿)

我发现了筛法的计算公式 孟庆馀[江苏连云港] 2010年5月 [摘要]: 笔者在探索中,发现了有关素数与合数关系的三条主要规律: 1、区段(区域)性的规律。 2、逐项相除四舍五入的规律。 3、随从数的规律。 根据这三条规律推导出一个公式, 它可以计算出任一已知素数后边紧跟的那个素数和任意大的一个自然数之前共有多少个素数的问题。 这个公式是: m p = 2N -N [ (211p p +311p p -3211p p p ±…±13211-n p p p p Λ)+ ( )1111132131211-±±++-n p p p p p p p p p ΛΛ(-n p 1)]+(1-n ) [关键词]: 筛法公式、逐项相除、四舍五入、区段、随从数。 [正文]: 笔者在多年的探索中,发现了有关素数与合数关系的一些规律,根据这些规律找到了一个可以对埃拉多斯染尼氏(Eratosthenes )筛法进行计算的公式,即“筛法计算公式”(它包括计算素数和计算奇合数两个公式),计算素数的公式也可以称为“素数公式"。给素数找出一个通项表达式,即已知任一素数后边紧跟的那个素数的公式,这是一个缠绕着数学家的世界难题,时至今日都没有解决。笔者的这个公式能较好地解决任一已知素数后边紧跟的那个素数的问题。 一、“筛法计算公式”(用于计算素数) m p = 2N -N [ (211p p +311p p -3211p p p ±…±13211-n p p p p Λ)+ ()1111132131211-±±++-n p p p p p p p p p ΛΛ(-n p 1)]+(1-n ) …(1) 式中m p 为1~N 数列中素数个数;N 为任意大的自然数(2n p ≤N <21+n p ) ;n p p p p ,,,,321K 为素数,其中:1p = 2,2p = 3,3p = 5,…,6p = 13,…;n ≥2 。

C语言习题100例

C程序100例 【程序1】 题目:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? 1.程序分析:可填在百位、十位、个位的数字都是1、2、3、4。组成所有的排列后再去 掉不满足条件的排列。 2.程序源代码: main() { int i,j,k; printf("\n"); for(i=1;i<5;i++) /*以下为三重循环*/ for(j=1;j<5;j++) for (k=1;k<5;k++) { if (i!=k&&i!=j&&j!=k) /*确保i、j、k三位互不相同*/ printf("%d,%d,%d\n",i,j,k); } } =========================================================== ===

【程序2】 题目:企业发放的奖金根据利润提成。利润(I)低于或等于10万元时,奖金可提10%;利润高 于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可可提 成7.5%;20万到40万之间时,高于20万元的部分,可提成5%;40万到60万之间时高于 40万元的部分,可提成3%;60万到100万之间时,高于60万元的部分,可提成1.5%,高于 100万元时,超过100万元的部分按1%提成,从键盘输入当月利润I,求应发放奖金总数? 1.程序分析:请利用数轴来分界,定位。注意定义时需把奖金定义成长整型。 2.程序源代码: main() { long int i; int bonus1,bonus2,bonus4,bonus6,bonus10,bonus; scanf("%ld",&i); bonus1=100000*0.1;bonus2=bonus1+100000*0.75; bonus4=bonus2+200000*0.5; bonus6=bonus4+200000*0.3; bonus10=bonus6+400000*0.15;

C语言求质数

试编写一个程序,找出2->N之间的所有质数。希望用尽可能快的方法实现。 【问题分析】: 这个问题可以有两种解法:一种是用“筛子法”,另一种是从2->N检查,找出质数。 先来简单介绍一下“筛法”,求2~20的质数,它的做法是先把2~20这些数一字排开: 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 先取出数组中最小的数,是2,则判断2是质数,把后面2的倍数全部删掉。 2 | 3 5 7 9 11 13 15 17 19 接下来的最小数是3,取出,再删掉3的倍数 2 3 | 5 7 11 13 17 19 一直这样下去,直到结束。 筛法求质数的问题时,非质数的数据有很多是重复的。例如,如果有一个数3×7×17×23,那么在删除3的倍数时会删到它,删7、17、23时同样也会删到它。有一种“线性筛法”,可以安排删除的次序,使得每一个非质数都只被删除一次。从而提高效率。因为“筛法”不是我要介绍的重点,所以就不介绍了。 现在我来介绍第二种方法。用这种方法,最先想到的就是让从2~N逐一检查。如果是就显示出来,如果不是,就检查下一个。这是正确的做法,但效率却不高。当然,2是质数,那么2的倍数就不是质数,如果令i从2到N,就很冤枉地测试了4、6、8……这些数?所以第一点改建就是只测试2与所有的奇数就足够了。同理,3是质数,但6、9、12……这些3的倍数却不是,因此,如果能够把2与3的倍数跳过去而不测试,任意连续的6个数中,就只会测试2个而已。以6n,6n+1,6n+2,6n+3,6n+4,6n+5为例,6n,6n+2,6n+4是偶数,又6n+3是3的倍数,所以如果2与3的倍数都不理会,只要测试的数就只留下6n+1和6n+5而已了,因而工作量只是前面想法的2/6=1/3,应该用这个方法编程。 还有个问题,就是如果判断一个数i是否为素数。按素数的定义,也就是只有1与本身可以整除,所以可以用2~i-1去除i,如果都除不尽,i就是素数。观点对,但却与上一点一样的笨拙。当i>2时,有哪一个数可以被i-1除尽的?没有,为什么?如果i不是质数,那么i=a×b,此地a与b既不是i又不是1;正因为a>1,a至少为2,因此b最多也是i/2而已,去除i的数用不着是2~i-1,而用2~i/2就可以了。不但如此,因为i=a×b,a与b不能大于sqrt(i),为什么呢?如果a>sqrt(i),b>sqrt(i),于是a×b>sqrt(i)*sqrt(i)=i,因此就都不能整除i了。如果i不是质数,它的因子最大就是sqrt(i);换言之,用2~sqrt(i)去检验就行了。 但是,用2~sqrt(i)去检验也是浪费。就像前面一样,2除不尽,2的倍数也除不尽;同理,3除不尽,3的倍数也除不尽……最理想的方法就是用质数去除i。 但问题是这些素数从何而来?这比较简单,可以准备一个数组prime[],用来存放找到的素数,一开始它里面有2、3、5。检查的时候,就用prime[]中小于sqrt(i)的数去除i即可,如果都除不尽,i就是素数,把它放如prime[]中,因此prime[]中的素数会越来越多,直到满足个数为止! 不妨用这段说明来编写这个程序,但是程序设计的时候会有两个小问题: 1.如果只检查6n+1和6n+5?不难发现,它们的距离是4、2、4、2……所以,可以先定义一个变量gab=4,然后gab=6-gab; 2.比较是不能用sqrt(i),因为它不精确。举个例子,i=121,在数学上,sqrt(i)自然是11,但计算机里的结果可能是10.9999999,于是去除的数就是2、3、5、7,而不含11,因此121就变成质数了。解决这个问题的方法很简单,不要用开方,用平方即可。例如,如果p*p<=i,则就用p去除i。而且它的效率比开方高。 【程序清单】: #include int creat_prime(int prime[],int n,int total)

素数普遍公式

素数普遍公式 目录[隐藏] 一、引言 二、素数普遍公式 三、素数的个数 四、公式的用途 五、素数普遍公式在认识形成中的作用和意义 思考题 一、引言 二、素数普遍公式 三、素数的个数 四、公式的用途 五、素数普遍公式在认识形成中的作用和意义 思考题 [编辑本段] 一、引言 2000多年前欧几里德在证明素数无穷多时就埋下了寻求素数普遍公式的伏笔 素数普遍公式 ,以布劳维尔为首的直觉主义学派认为:“你没有给出第n个素数是如何构造的,就不能算是好的证明”。2000多年来,数论学最重要的一个任务,就是寻找素数普遍公式,为此,一代又一代数学精英,耗费了巨大的心血,始终未获成功。黎曼曾想用他的ζ函数数的“零点”来逼近素数普遍公式,至今未获成功。也有人反向思考,用素数普遍公式逼近“零点”来解决黎曼猜想。希尔伯特在1900年的国际数学家大会上说:对黎曼公式进行了彻底讨论之后,或许就能够严格解决哥德巴赫问题和孪生素数问题。实际在哲学上,只要有一个明确的定义,就应该有一个公式。 [编辑本段] 二、素数普遍公式

公元前250年同样是古希腊的数学家埃拉托塞尼提出一种筛法: (一)“要得到不大于某个自然数N的所有素数,只要在2---N中将不大于√N的素数的倍数全部划去即可”。 (二)将上面的内容等价转换:“如果N是合数,则它有一个因子d满足1

C语言求素数(质数)Eratosthenes经典算法

//使用Eratosthenes方法找出指定范围内的所有质数 #include #define SIZE 500 //该方法能够求出2*SIZE 之内的质数#define TRUE 1 #define FALSE 0 int main() { char sieve[ SIZE ]; /* the sieve */ char *sp; /* pointer to access the sieve */ int number; /* number we’re computing */ /* ** Set the entire sieve to TRUE. */ for(sp = sieve; sp<&sieve[ SIZE ]; ) *sp++ = TRUE; /*** Process each number from 3 to as many as the sieve holds. (Note: the ** loop is terminated from inside.) */ for( number = 3; ; number += 2 ){ /* ** Set the pointer to the proper element in the sieve, and stop ** the loop if we’ve gone too far. */ sp = &sieve[ 0 ] + ( number-3 ) / 2; if(sp>= &sieve[ SIZE ] ) break; /* ** Now advance the pointer by multiples of the number and set ** each subsequent entry FALSE. */ while(sp += number, sp<&sieve[ SIZE ] ) *sp = FALSE; } /* ** Go through the entire sieve now and print the numbers corresponding ** to the locations that remain TRUE. */ printf( "2\t" ); for( number = 3, sp = &sieve[ 0 ]; sp<&sieve[ SIZE ]; number += 2, sp++ ){ if( *sp ) printf( "%d\t", number );

筛法求素数

筛法求素数 目录 基本思想 C语言实现 pascal实现: 1C++实现: 2python 实现: 基本思想 用筛法求素数的基本思想是:把从1开始的、某一范围内的正整数从小到大顺序排列,1不是素数,首先把它筛掉。剩下的数中选择最小的数是素数,然后去掉它的倍数。依次类推,直到筛子为空时结束。如有: 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 27 28 29 30 1不是素数,去掉。剩下的数中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 29 C语言实现 1、算法一:令A为素数,则A*N(N>1;N为自然数)都不是素数。 #define range 2000 bool IsPrime[range+1]; //set函数确定i是否为素数,结果储存在IsPrime[i]中,此函数在DEV C++中测试通过 void set(bool IsPrime[]) { int i,j; for(i=0;i<=range;++i) IsPrime[i]=true; IsPrime[0]=IsPrime[1]=false; for(i=2;i<=range;++i) { if(IsPrime[i]) { for(j=2*i;j<=range;j+=i) IsPrime[j]=false; } } } 2、 说明:解决这个问题的诀窍是如何安排删除的次序,使得每一个非质数都只被删除一次。中学时学过一个因式分解定理,他说任何一个非质(合)数都可以分解成质数的连乘积。例如,16=4^2,18=2 * 3^2,691488=2^5 * 3^2 * 7^4等。如果把因式分解中最小质数写在最左边,有16=4^2,18=2*9,691488=2^5 * 21609,;换句话说,把合数N写成N=p^k * q,此时q当然是大于p的,因为p是因式分解中最小的质数。由于因式分解的唯一性,任何一个合数N,写成N=p^k * q;的方式也是唯一的。由于q>=p的关系,因此在删除非质数时,如果已知p是质数,可以先删除P^2,p^3,p^4,... ,再删除pq,p^2*q,p^3*q,...,(q是比p大而没有被删除的数),一直到pq>N为止。 因为每个非质数都只被删除一次,可想而知,这个程序的速度一定相当快。依据Gries与Misra的文章,线性的时间,也就是与N成正比的时间就足够了(此时要找出2N的质数)。(摘自《C语言名题精选百则(技巧篇)》,冼镜光编著,机械工业出版社,2005年7月第一版第一次印刷)。代码如下: #include #include using namespace std; int main() { int N; cin>>N; int *Location=new int[N+1]; for(int i=0;i!=N+1;++i) Location[i]=i; Location[1]=0; //筛除部分int p,q,end; end=sqrt((double)N)+1; for(p=2;p!=end;++p) { if(Location[p]) { for(q=p;p*q<=N;++q) { if(Location[q]) { for(int k=p*q;k<=N;k*=p) Location[k]=0; } } } } int m=0; for(int i=1;i!=N+1;++i) { if(Location[i]!=0) { cout<

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

例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; Begin Fillchar(a,sizeof(a),true); a[1] := False; for i:=2 to Trunc(sqrt(N)) do if a[I] then for j := 2 to N div I do a[I*j]:= False; t:=0; for i:=2 to N do if a[i] then Begin write(a[ i ]:5); inc(t); if t mod 5=0 then writeln end; End. 【例3】输入十个正整数,把这十个数按由大到小的顺序排列(将数据按一定顺序排列称为排序,排序的算法有很多,其中选择排序中的“简单选择排序”是一种较简单的方法) 分析:要把十个数按从大到小顺序排列,则排完后,第一个数最大,第二个数次大,……;因此,我们第一步可将第一个数与其后的各个数依次比较,若发现,比它大的,则与之交换,比较结束后,则第一个数已是最大的数。同理,第二步,将第二个数与其后各个数再依次比较,又可得出次大的数。如此方法进行比较,最后一次,将第九个数与第十个数比较,以决定次小的数。于是十个数的顺序排列结束。 例如下面对5个进行排序,这个五个数分别为829105。按选择排序方法,过程如

C语言经典算法100例题目

看懂一个程序,分三步:1、流程;2、每个语句的功能;3、试数;小程序:1、尝试编程去解决他;2、看答案;3、修改程序,不同的输出结果; 4、照答案去敲; 5、调试错误; 6、不看答案,自己把答案敲出来; 7、实在不会就背会。。。。。周而复始,反复的敲。。。。。 【程序1】 题目:有1、2、3、 4 个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?【程序2】 题目:企业发放的奖金根据利润提成。利润(I) 低于或等于10 万元时,奖金可提10%;利润高于10 万元,低于20 万元时,低于10 万元的部分按10%提成,高于10 万元的部分,可可提成7.5%;20万到40万之间时,高于20万元的部分,可提成5%;40万到60万之间时高于40万元的部分,可提成3%;60 万到100万之间时,高于60万元的部分,可提成 1.5%,高于100 万元时,超过100 万元的部分按1%提成,从键盘输入当月利润I ,求应发放奖金总数?【程序3】 题目:一个整数,它加上100 后是一个完全平方数,再加上168 又是一个完全平方数,请问该数是多少?【程序4】 题目:输入某年某月某日,判断这一天是这一年的第几天? 【程序5】 题目:输入三个整数x,y,z ,请把这三个数由小到大输出 【程序6】 题目:用*号输出字母 C 的图案 【程序7】 题目:输出特殊图案,请在 c 环境中运行,看一看,Very Beautiful! 【程序8】题目:输出9*9 口诀 【程序9】题目:要求输出国际象棋棋盘。 【程序10】题目:打印楼梯,同时在楼梯上方打印两个笑脸。 【程序11】 题目:古典问题:有一对兔子,从出生后第 3 个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 【程序12】 题目:判断101-200 之间有多少个素数,并输出所有素数。 【程序13】 题目:打印出所有的“水仙花数” ,所谓“水仙花数”是指一个三位数,其各位数字立方和等于该数本身。例如:153是一个“水仙花数” ,因为153=1的三次方+5的三次方+ 3 的三次方。 【程序14】

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

C 使用筛选法求100以内的素数 C++使用筛选法求100以内的素数,具体问题分析及其代码如下: 【问题分析】 我们可以把100个数看作是沙子和石子,素数是石子,非素数的是沙子,弄个筛子,将沙子筛掉,剩下的就是素数。 1至100这些自然数可以分为三类: (1) 单位数:仅有一个数1. (2) 素数:这个数大于1,且只有它本身和1这样两个正因数。 (3) 合数:除了1和他自身以外,还有其他的正因数。 【代码如下】 /******************************************************** /* 程序名:素数筛选 /* 编程时间:2009年7月27日 /* 主要功能:求素数 *********************************************************/ #include using namespace std;//编译命令 #include const int MAX=100;//定义常量MAX int 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;//将原数扩大二倍初始化给j do { prime[j]=1;//将j筛掉 j+=i; //再扩大一倍 } while(j<=MAX);//直到最大 } } for(i=2; i<=MAX; i++) { if(prime[i]==0)//循环输出 cout<

(完整版)C语言100个经典题目

C语言程序设计习题 授课对象:信息奥赛辅导成员 授课时间: 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔 子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数 为多少? __________________________________________________________________ 程序分析:兔子的规律为数列1,1,2,3,5,8,13,21…. ___________________________________________________________________ 程序源代码: main() { long f1,f2; int i; f1=f2=1; for(i=1;i<=20;i++) { printf(“%12ld %12ld”,f1,f2); if(i%2==0) printf(“\n”);/*控制输出,每行四个*/ f1=f1+f2;/*前两个月加起来赋值给第三个月*/ f2=f1+f2;/*前两个月加起来赋值给第三个月*/ } } 上题还可用一维数组处理,you try! 题目:判断101-200之间有多少个素数,并输出所有素数。 __________________________________________________________________ 程序分析:判断素数的方法:用一个数分别去除2到sqrt(这个数),如果能被整除,则表明此数不是素数,反之是素数。 ___________________________________________________________________ 程序源代码: #include “math.h” main() { int m,i,k,h=0,leap=1;

C语言求素数问题算法

1.自然数是0,1,2…… 2.素数是2,3,5……(不包括1的只能背1和它本身整除的自然数) 【1】求10000以内的所有素数。 素数是除了1和它本身之外再不能被其他数整除的自然数。由于找不到一个通项公式来表示所有的素数,所以对于数学家来说,素数一直是一个未解之谜。像著名的哥德巴赫猜想、孪生素数猜想,几百年来不知吸引了世界上多少优秀的数学家。尽管他们苦心钻研,呕心沥血,但至今仍然未见分晓。 自从有了计算机之后,人们借助于计算机的威力,已经找到了2216091以内的所有素数。 求素数的方法有很多种,最简单的方法是根据素数的定义来求。对于一个自然数N,用大于1小于N的各个自然数都去除一下N,如果都除不尽,则N为素数,否则N为合数。 但是,如果用素数定义的方法来编制计算机程序,它的效率一定是非常低的,其中有许多地方都值得改进。 第一,对于一个自然数N,只要能被一个非1非自身的数整除,它就肯定不是素数,所以不 必再用其他的数去除。 第二,对于N来说,只需用小于N的素数去除就可以了。例如,如果N能被15整除,实际 上就能被3和5整除,如果N不能被3和5整除,那么N也决不会被15整除。 第三,对于N来说,不必用从2到N一1的所有素数去除,只需用小于等于√N(根号N)的所有素数去除就可以了。这一点可以用反证法来证明: 如果N是合数,则一定存在大于1小于N的整数d1和d2,使得N=d1×d2。 如果d1和d2均大于√N,则有:N=d1×d2>√N×√N=N。 而这是不可能的,所以,d1和d2中必有一个小于或等于√N。 基于上述分析,设计算法如下: (1)用2,3,5,7逐个试除N的方法求出100以内的所有素数。 (2)用100以内的所有素数逐个试除的方法求出10000以内的素数。 首先,将2,3,5,7分别存放在a[1]、a[2]、a[3]、a[4]中,以后每求出一个素数,只要不大于100,就依次存放在A 数组中的一个单元中。当我们求100—10000之间的素数时,可依次用a[1]-a[2]的素数去试除N,这个范围内的素数可以不保存,直接打印。 【2】用筛法求素数。 简单介绍一下厄拉多塞筛法。厄拉多塞是一位古希腊数学家,他在寻找素数时,采用了一种与众不同的方法:先将2-N的

求100—200内所有素数

求100——200内所有素数 ①要判断一个数是不是素数,首先要知道什么是素数。回忆一下数学里的知识,什么是素数?只能被自身和1整除的正整数是素数。1既不是素数,也不是合数;2是最小的素数,也是唯一一个是偶数的素数。 ②判断一个正整数m是否为素数有多种方法。 方法1:让m依次被2,3,…,m-1除,如果m不能被2~m-1中的任何一个整数整除,则m是素数。 方法2:让m依次被2,3,…,m/2除,如果m不能被2~m/2中的任何一个整数整除,则m是素数。 方法3:让m依次被2,3,…,sqrt(m)除,如果m不能被2~sqrt(m)中的任意一个整数整除,则m为素数。sqrt(m)为m的平方根。 其中最后一种方法判断速度最快,因此这里采用最后一种方法。 ③判断一个整数是不是素数,由于需要一次一次地做除法,所以要使用循环。 程序如下: #include "math.h" main( ) { int m,i,k,n=0; for(m=101; m<=200; m+=2) { k=sqrt(m); for (i=2;i<=k;i++) if (m%i==0) break; if (i>k) {printf("%5d",m); n=n+1; if (n%10==0) printf("\n"); } } } 运行结果为: 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199
本文来自【C语言中文网】:https://www.360docs.net/doc/e010266793.html,/cpp/html/664.html

素数的几种判断方法和实现

PS:本来没有决心把这个东西写完的,结果早上写到一半,出去吃个饭,没保存,回来手一抖直接关掉了,好不容易写了一大半了,只能重新写了,坑爹啊,但就是这个插曲,本来还没有决心的我,一下子却坚定了信念,一点要把这个东西写完。就这样开始吧 BY:Lee 下面,我们重新开始 ═══════════════════════════════════════════ 如何判断一个数是否是素数呢 ═══════════════════════════════════════════也许你会认为这是一个简单的问题,但事实上,世界上任何一个问题,都没有你想象中的那么简单1 + 1 是否等于2 ,这便是一个简单而又复杂的问题,呵呵。 突然想把这个东西换一种风格来写了,就这样扯淡扯下去吧。扯的时候文章中多少有内容来自于网络,没有侵权的意思,如果作者看到还请见谅。 ═══════════════════════════════════════════下面正式进入正题 ═══════════════════════════════════════════ 一、朴素判断素数 ═══════════════════════════════════════════1. 这种方法被誉为笨蛋的做法: 一个数去除以比它的一半还要大的数,一定除不尽的,这还用判断吗?? 很容易发现的,这种方法判断素数,对于一个整数n,需要n-2 次判断,时间复杂度是O(n)在n非常大或者测试量很大的时候,这种笨蛋做法肯定是不可取的。

2. 改进一下下小学生的做法: 3. 再改进一下聪明的小学生的做法 对于一个小于n的整数X,如果n不能整除X,则n必定不能整除n/X。反之相同一个明显的优化,就是只要从2枚举到√n 即可。 因为在判断2的同时也判断了n/2。到√n时就把2到n-1都判断过了。 在这里,这个聪明的小学生还用了i*i <= n 来代替sqrt(n), 这里是避免了调用函数sqrt(),其消耗时间很大, 特别是在大量数据测试的时候消耗很明显。 这个算法的时间复杂度,与最前面的笨蛋做法就好多了, 不过这里好像用sqrt()也没问题啊,,,,这个就不太清楚了。 但是做一个测试发现,如果是这样额话,每一次判断都要计算i*i,

线性筛法求素数的原理与实现

何为线性筛法,顾名思义,就是在线性时间内(也就是O(n))用筛选的方法把素数找出来的一种算法,没用过线性筛素数法的人可能会奇怪,用遍历取余判定素数不是也是线性时间的吗,没错,但是确切的说线性筛法并不是判定素数的,而是在线性时间内求出一个素数表,需要判定是否是素数的时候只要看该数是否在表内就可以瞬间知道是不是素数。 比如想求10000以内的素数,定义表int a[10000],进行线性筛选后,a[n]的值就代表n是不是素数,a[n]如果是1,就代表n是素数,a[n]如果是0,就代表n不是素数,这就是查表。再判定其他的素数也是一样,不用再做任何计算。 而如果用遍历取余,那么每判定一个数都要从头开始再遍历一遍,而线性筛法只在开始一次性运算完,以后只要查表即可,查表通常只需要1条语句。所以如果你的程序从始至终只需要判定那么几次素数那么用遍历取余即可,但是如果需要多次判定素数,而且这个数还不是很小的话,那么线性筛法就会体现出巨大的优越性来。 线性筛法的核心原理就是一句话:每个合数必有一个最大因子(不包括它本身),用这个因子把合数筛掉,还有另一种说法(每个合数必有一个最小素因子,用这个因子筛掉合数,其实都一样,但是我觉得这种方法不太容易说明,这种方法我会在最后给出简略说明)。这个很容易证明:这个小学就知道合数一定有因子,既然是几个数,就一定有最大的一个。最大因子是唯一的,所以合数只会被它自己唯一的因子筛掉一次,把所有合数筛掉后剩下的就全是素数了。 先假设一个数i,一个合数t,i是t最大的因数,t显然可能并不唯一(例如30和45的最大因数都是15)。那么如何通过i知道t呢,t必然等于i乘以一个比i小的素数。先来说这个数为什么一定要比i小,这很显然,如果是i乘上一个比它大的素数,那么i显然不能是t 最大的因子。再来说为什么要是素数,因为如果乘上一个合数,我们知道合数一定可以被分解成几个素数相乘的结果,如果乘上的这个合数x=p1*p2*……,那么 t = i * x = i * p1 * p2……很显然p1* i也是一个因数,而且大于i。所以必须乘上一个素数。 比i小的素数一定有不少,那么该乘哪一个呢,既然t不唯一,那么是不是都乘一遍呢?很显然不行,虽然t不唯一,但全乘一遍很显然筛掉的数的数量远远超过合数的数量。我们先给出结论: 任意一个数i = p1*p2*……*pn,p1、p2、……pn都是素数,p1是其中最小的素数, 设T 为i * M的积(显然T就成了一个合数),也就是T = i * M,(M是素数,并且M<=p1),那么T的最大的因数就是i。 是的,乘上的数要小于等于i最小的质因数。

素数的线性筛法

素数的线性筛法 //整体思想是从自然数 2 开始与所有之前已经确定的素数相乘后的数标记为合数就能把素数一个不漏地找出来 #include #include #include #include #include #include #include #include #include #include #include #include #define MID(x,y) ( ( x + y ) >> 1 ) #define L(x) ( x << 1 ) #define R(x) ( x << 1 1 ) #define FOR(i,s,t) for(int i=(s); i<(t); i++) #define FORD(i,s,t) for(int i=(s-1); i>=t; i--) #define BUG puts("here!!!") #define STOP system("pause") #define file_r(x) freopen(x, "r", stdin) #define file_w(x) freopen(x, "w", stdout) using namespace std; const int SULEN = 1000000; bool flag[SULEN+1];// 是否为素数 int prime[1000001];// 存储的素数 int sum[SULEN+1];//n 的所有质因子的和 void xianxingshai(void) { int count,i,j; fill( flag,flag+SULEN,true ); // 初始化假设每个都为素数 fill( sum ,sum +SULEN, 0 ); //初始化质因子和为0 flag[0] = flag[1] = false; //0 和 1 不是素数 for( count = 0, i = 2; i <= SULEN; i++ )// 从 2 开始判断是否为素数 { if( flag[i] ) // 如果是素数 { prime[count++] = i;sum[i] = i; //将值传到prime 数组中 } for( j = 0; j < count && i*prime[j] <= SULEN; j++ ) // 将包含该质因数的合数都 标为 false

用C++或C语言编写出100以内所有互为质数的勾股数

C++:#include "iostream.h" using namespace std; int fun(int an,int bn,int cn) { int a,b,t; a = an; b = bn; if(a < b) { t = a; a = b; b = t; } while(t=a%b) { a = b; b = t; } if(b == 1) { cout<

C:#include int fun(int an,int bn,int cn) { int a,b,t; a = an; b = bn; if(a < b) { t = a; a = b; b = t; } while(t=a%b) { a = b; b = t; } if(b == 1) { printf("%d %d %d\n",an,bn,cn); return 0; } else { return 0; } } int main(int a,int b,int c) { for(a=1;a<100;a++) for(b=a;b<100;b++) for(c=b;c<100;c++) if(c*c==a*a+b*b) {fun(a,b,c); } return 0; }

质数分解

★引子 前天,俺在《俺的招聘经验[4]:通过笔试答题能看出啥?》一文,以"求质数"作为例子,介绍了一些考察应聘者的经验。由于本文没有政治敏感内容,顺便就转贴到俺在CSDN 的镜像博客。 昨天,某个CSDN网友在留言中写道: 老实说,这个程序并不好写,除非你背过这段代码 如果只在纸上让别人写程序,很多人都会出错 但是如果给一台电脑,大多数人都会把这个程序调试正确 出这个题目没啥意义 只能让别人觉得你出题水平低 首先,这位网友看帖可能不太仔细。俺在文中已经专门强调过了,评判笔试答题,"思路和想法"远远比"对错"更重要,而他/她依然纠结于对错;其次,这位网友居然觉得这道题目没啥意义,这让俺情何以堪啊?!看来,有相当一部分网友完全没有领略到此中之奥妙啊! 算了,俺今天就豁出去了,给大伙儿抖一抖这道题目的包袱。当然,抖包袱的后果就是:从今天开始,就得把"求质数"这道题从俺公司的笔试题中去掉,然后换上另外一道全然不同的。这么好的一道题要拿掉,真是于心不忍啊 :-( ★题目 好,言归正传。下面俺就由浅入深,从各种角度来剖析这道题目的奥妙。 为了避免被人指责为"玩文字游戏"(有些同学自己审题不细,却抱怨出题的人玩文字游戏),在介绍各种境界之前,再明确一下题意。 前一个帖子已经介绍过,求质数可以有如下2种玩法。 ◇需求1 请实现一个函数,对于给定的整型参数 N,该函数能够把自然数中,小于 N 的质数,从小到大打印出来。 比如,当 N = 10,则打印出 2 3 5 7 ◇需求2 请实现一个函数,对于给定的整型参数 N,该函数能够从小到大,依次打印出自然数中最小的 N 个质数。

比如,当 N = 10,则打印出 2 3 5 7 11 13 17 19 23 29 ★试除法 首先要介绍的,当然非"试除法"莫属啦。考虑到有些读者是菜鸟,稍微解释一下。 "试除",顾名思义,就是不断地尝试能否整除。比如要判断自然数 x 是否质数,就不断尝试小于 x 且大于1的自然数,只要有一个能整除,则 x 是合数;否则,x 是质数。 显然,试除法是最容易想到的思路。不客气地说,也是最平庸的思路。不过捏,这个最平庸的思路,居然也有好多种境界。大伙儿请看: ◇境界1 在试除法中,最最土的做法,就是: 假设要判断 x 是否为质数,就从 2 一直尝试到 x-1。这种做法,其效率应该是最差的。如果这道题目有10分,按照这种方式做出的代码,即便正确无误,俺也只给1分。 ◇境界2 稍微聪明一点点的程序猿,会想:x 如果有(除了自身以外的)质因数,那肯定会小于等于 x/2,所以捏,他们就从 2 一直尝试到 x/2 即可。 这一下子就少了一半的工作量哦,但依然是很笨的办法。打分的话,即便代码正确也只有2分 ◇境界3 再稍微聪明一点的程序猿,会想了:除了2以外,所有可能的质因数都是奇数。所以,他们就先尝试 2,然后再尝试从 3 开始一直到 x/2 的所有奇数。 这一下子,工作量又少了一半哦。但是,俺不得不说,依然很土。就算代码完全正确也只能得3分。 ◇境界4 比前3种程序猿更聪明的,就会发现:其实只要从 2 一直尝试到√x,就可以了。估计有些网友想不通了,为什么只要到√x 即可? 简单解释一下:因数都是成对出现的。比如,100的因数有:1和100,2和50,4和25,5和20,10和10。看出来没有?成对的因数,其中一个必然小于等于100的开平方,另一个大于等于100的开平方。至于严密的数学证明,用小学数学知识就可以搞定,俺就不啰嗦了。◇境界5 那么,如果先尝试2,然后再针对 3 到√x 的所有奇数进行试除,是不是就足够优了

相关文档
最新文档