c语言程序0到1000的素数,C语言实现之100-1000以内素数的等差数列

接上一篇,还是我同学给的题目,最后一个。一开始有点问题,现在改正了。

*写的比较仓促,如果有更简便、执行效率更高的方法还请不吝赐教,当然我的如果有问题请大家给指出。

题目:

在小于10的素数中有3、5、7组成的等差数列,在小于30的素数中有11、17、23、29组成的等差数列。

试找出区间[100,1000]内的素数构成的最大等差数列(即等差数列包含的素数个数最多)并打印输出。

分析:

(1)要在100-1000中找等差数列,为了提高效率,肯定是先生成100-1000之间的素数表之类的东西,然后再从中找。

(2)注意的是,公差有可能会比较大,以至一个素数和它之后数个素数之后的素数存在等差关系。

思路:

我是这样想的,先生成一个素数表,牺牲点内存省点劲,这个表建1001个元素,直接用下标指代元素,用0表示素数,1表示非素数,因为从100开始,所以之前的就不管了。等差值从2直到900,依次尝试,并从101开始,如果加上公差之后不是素数,则找下一个素数,再从下一个素数开始,直到下一个素数找过1000,在尝试下一个公差,以此搜索所有可能,将长度最大数列的第一个元素、公差和长度记录下来,判断完所有的之后打印出来。

实现:

(这里检索素数用的是筛选的方法,将其中能整出比自己小的素数的数字踢出,应为他们一定是合数,剩下的就是素数了)

#include

#include

int primeNum[1001];

/********************************************************

*函  数:void setPrime()                                *

*参  数:无                                             *

*功  能:判断100-1000的素数并将对应下标的数组值置位   *

*返  回:无                                             *

*********************************************************/

void setPrime()

{

int flag;                                       //标志位,表示存在除1,和他自身之外能被他整除的数字

int loop;

int site = 2;

memset(primeNum, 0, 1000 * sizeof(int));        //初始化数组所在内存区

while(1)

{

flag = 1;                                   //标志位初始化置为

for(loop = site + 1; loop <= 1000; loop++)

{

//判断当时是否是素数(避免重复判断)

if(!primeNum[loop])

{

if(loop % site == 0)

{

primeNum[loop] = 1;             //不是素数置位1

}

else

{

if(flag)

{

flag = 0;                   //清空标志位

site = loop;

}

}

}

}

if(flag)

{

break;                                  //没找到过说明在此之后不再有素数(即查找完毕)

}

}

}

/***************************************************************

*函  数:int getNextPrime(int site)                            *

*参  数:当前的素数                                           *

*功  能:判断100-1000的素数中指定素数的下一个素数            *

*返  回:如果100-1000以内有下一个素数返回次数,否则返回-1   *

****************************************************************/

int getNextPrime(int site)

{

while(site < 1001 && primeNum[++site]);

return site > 1000 ? -1 : site;

}

/*****************************

*函  数:int main()         *

*参  数:无                  *

*功  能:主函数              *

*返  回:无                  *

*****************************/

int main()

{

int loop = 1;                                       //公差

int circle;

int lastA = 2;                                      //记录上一次的公差

int lastStart = 101;                                //记录上一次的数列起始位置

int lastCount = 0;                                  //记录上一次数列长度

int count;                                          //记录此次数列长度

int start;                                          //记录此次数列起始位置

int flag = 1;                                       //标志位,表示以此判断中第一次遇到素数

setPrime();

while(++loop <= 900)

{

for(circle = 101; circle < 1001; circle += loop)

{

//判断标志位,是不是此次判断的第一个

if(flag)

{

flag = 0;                               //清空标志

start = circle;                         //记录数列开始元素

count = 0;                              //重置数列元素个数

}

if(primeNum[circle])

{

flag = 1;                               //置位标志位

circle = getNextPrime(circle);          //判断下一个素数

if(circle < 0)

{

break;                              //不存在下一个素数,跳出循环,继续进行公差递增后的判断

}

else

{

continue;                           //继续判断

}

}

count++;                                    //如果执行到这,说明当前的数列目前还满足条件,总量计数递增

}

//判断此次判断的数列总数是否比之前的大

if(count > lastCount)

{

lastCount = count;                          //记录当前的数列总数

lastA = loop;                               //记录当前的公差

lastStart = start;                          //记录当前的数列起始元素

}

}

//循环输出最大数列的所有元素

while(lastCount--)

{

printf("%d ", lastStart);

lastStart += lastA;                             //计算下一个元素

}

return 0;

}

结果:

101 281 461 641 821

(5个)

总结:

前几个一直都是用递归,这个用循环吧,可能就是循环那想起来有点乱,但是想清楚其实嵌套的并不复杂。当然我不知道我写的对不对,如果有错还麻烦你告诉我。我也不知道我的这种写法是不是麻烦,这是我很直观想到的方法,如果大家有更好的方法还请不吝赐教。终于发完了,困死我了

0818b9ca8b590ca3270a3433284dd417.png

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值