C语言新手 给定一段连续的正整数,请判断其中素数的个数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言新手 给定一段连续的正整数,请判断其中素数的个数相关的知识,希望对你有一定的参考价值。

输入数据包含2个正整数A和B(0<A<B<=100000),分别表示连续整数段的2端 用数组 很乱求助

#include<stdio.h>
#include<math.h>
void main()

long int a[100000], x, y, i, j, k, z, m, s;
scanf("%d%d",&x, &y);
z = y - x - 1;
m = 0;
for(i = 0; i < z; i++)

x++;
a[i] = x ;

for(i = 0;i < z;i++)

if(a[i] > 0)

for(j = 2;j <= sqrt(a[i]);j++)

k = a[i] / j;
if(k == 0)

goto s;

m++;


s:;

printf("%d", m);

改过的,有注释,对照看……
void main(void)
long int a[100000], x, y, i, j, k, z, m, s;
scanf("%d%d",&x, &y);
z = y - x - 1;
m = 0;
for(i = 0; i < z; i++)

x++;
a[i] = x ;

for(i = 0;i < z;i++)

if(a[i] > 0)

for(j = 2;j <= sqrt(a[i]);j++)

//k = a[i] / j;/错了,应为%
k = a[i] % j;//这个才对.
if(k == 0)

goto s;

//m++;//地方不对,所以逻辑错.

m++;//放到这里才对.

else//加这个判断以完善逻辑.
printf("Negative!\n");
return;

s:;

printf("%d", m);
追问

是否可以加个if判断当x=1 , 2, 3 时 直接 m++ 呢? 貌似 j初值为 2 , 1,和2就被排除了

参考技术A

/*

100 1000

   101   103   107   109   113   127   131   137   139   149

   151   157   163   167   173   179   181   191   193   197

   199   211   223   227   229   233   239   241   251   257

   263   269   271   277   281   283   293   307   311   313

   317   331   337   347   349   353   359   367   373   379

   383   389   397   401   409   419   421   431   433   439

   443   449   457   461   463   467   479   487   491   499

   503   509   521   523   541   547   557   563   569   571

   577   587   593   599   601   607   613   617   619   631

   641   643   647   653   659   661   673   677   683   691

   701   709   719   727   733   739   743   751   757   761

   769   773   787   797   809   811   821   823   827   829

   839   853   857   859   863   877   881   883   887   907

   911   919   929   937   941   947   953   967   971   977

   983   991   997

Press any key to continue

*/

#include <stdio.h>
#include <math.h>

int main() 
long int i,j,flag,m,n,t,cnt = 0;
scanf("%d%d",&m,&n);
if(m > n)  t = m; m = n; n = t; 
for(i = m; i <= n; ++i) 
if(i < 2) continue;
if(i == 2)  printf("%6d",2); ++cnt; continue; 
flag = 1;
for(j = 2;j <= sqrt(i) && flag; ++j) 
if(i % j == 0) flag = 0;

if(flag) 
if(cnt && cnt % 10 == 0) printf("\\n");
printf("%6d",i);
++cnt;


if(cnt % 10) printf("\\n");
return 0;

参考技术B #include "stdlib.h"
#include "math.h"
int a[1000010]=0;
int main()
int i,j,min,max,s=0;
scanf("%d%d",&min,&max);
for(i=2;i<=sqrt(max);i++)//筛选求素数,这个速度比单个求解要快。
if(a[i]==1)
continue;
else
for(j=i;i*j<=max;j++)
a[i*j]=1;
for(i=min;i<=max;i++)
if(a[i]==0)
s++;printf("%d\t",i);
printf("%d",s);
system("pause");
return 0;

c语言:实现对于给定的正整数N,依次打印出小于等于N的所有素数。两种方法及其优化

编写一个程序实现对于给定的整数N,依次打印出小于等于N的所有素数。

方法一:试除法

由素数的定义到如下程序

#include<stdio.h>

int print_prime(int num)//prime表示素数

int i = 0;

for (i = 2; i <= num; i++)

int j = 0;

for (j = 2; j < i; j++)

if (i%j == 0)

break;

if (i==j)

printf("%d\\t",i);

int main()

int num;

printf("请输入一个正整数:");

scanf("%d", &num);

if (num > 1)

printf("打印出所有的素数:");

print_prime(num);

else

printf("不存在小于等于%d的素数", num);

printf("\\n");

return 0;

上面的代码中,在判断素数时一直从2试除到n-1。这里从n/2之后的数到n-1的试除显然是多余的,比如正整7不能被2整除,必然不能被4,6整除。

优化1:

试除的范围优化到[2,n/2],工作量减少一半,代码如下:

int print_prime(int num)//prime表示素数

int i = 0;

for (i = 2; i <= num; i++)

int j = 0;

for (j = 2; j <= i/2; j++)//修改部分

if (i%j == 0)

break;

if (j == (i/2+1))//修改部分

printf("%d\\t", i);

    既然能将试除范围优化到[2,n/2],那么这个范围是不是还能继续优化呢?答案是肯定的,在[2,n/2]这个范围里(√n,n/2]的试除也是多余的。因为因数是成对出现的,如16可分解为:1和16 、2和8、4和4、8和2、16和1。这些因数里必然有一个小于等于4。只需试除小于等于√n的数就可以了。

优化2:

      试除范围优化为[2,√n],代码如下:

#include<stdio.h>

#include<math.h>//修改部分

int print_prime(int num)//prime表示素数

int i = 0;

for (i = 2; i <= num; i++)

int j = 0;

for (j = 2; j <=sqrt(i); j++)//修改部分

if (i%j == 0)

break;

if (j > sqrt(i))//修改部分

printf("%d\\t", i);

    上面所有的代码在找素数的时候是从2到n,在这个范围内除了2之外的偶数都不是素数,所以可以跳过这些偶数。

    还有试除范围内除了2之外的偶数也是没有必要的,因为如果不能被2整除,必然不能被大于2的偶数整除。

优化3:

    寻找素数时试除范围跳过除2之外的偶数。代码如下:

int print_prime(int num)//prime表示素数

int i = 0;

printf("%d\\t", 2);//修改部分

for (i = 3; i <= num; i+=2)//修改部分

int j = 2;

for (j = 3; j <= sqrt(i); j+=2)//修改部分

if (i%j == 0)

break;

if (j > sqrt(i))

printf("%d\\t", i);

    在上面的代码中,试除范围内的一些数也是不必要的。比如判断101是否为素数时,要分别试除小于10的2和所有奇数,即2、3、5、7、9,其中对9的试除是不必要的。即对所有的非素数的试除是不必要的,因为非素数必然可分解为比它小的素数的乘积,既然它的质因数不能整除某个数,这个数必然也不能。故试除的范围可缩小到小于等于√n的所有素数。

优化4:

    只试小于√n的素数,那么问题来了,要试除这些素数时必然要将前面求出的素数保存起来,开辟多大一块空间合适呢?因为n的大小未知,所以无法确定开辟多少空间。这里暂时没有完全解决的办法,我的做法是先开辟大小为1000的空间,需要时再修改。

#include<stdio.h>

#include<math.h>

#define MAX 1000  //定义数组的大小

int print_prime(int num)//prime表示素数

int arr[MAX] = 0 ;

int i = 0,j=1;

printf("%d\\t", 2);

arr[0] = 2;

for (i = 3; i <= num; i += 2)

int k = 0;

while (arr[k]>0&&arr[k]<=sqrt(i))

if (i%arr[k] == 0)

break;

k++;

if (!arr[k]||(arr[k] > sqrt(i)))

printf("%d\\t", i);

arr[j] = i;

j++;

int main()

int num;

printf("请输入一个正整数:");

scanf("%d",&num);

if (num > 1)

printf("打印出所有的素数:");

print_prime(num);

else

printf("不存在小于等于%d的素数",num);

printf("\\n");

return 0;

方法二:筛

    这种方法求素数的思想就是,不断筛去最小的数的倍数。这个最小的数必然是素数。

    比如最小的素数是2,去掉所有2的倍数;接下来最小的数是3,3就是素数,去掉所有的3的倍数;依次类推,直到最小的数小于等于√n为止。为什么是√n呢? 在上面的试除法中讲到只要试除小于等于√n的所有素数即可判断出小于等于n的所有素数,这里同样适用,只要去掉所有的小于等于√n的所有数的倍数,剩下的数就是小于等于n的所有素数。

代码如下:

#include<stdio.h>

#include<math.h>

#define MAX 1000  //定义数组的大小

int print_prime(int num)//prime表示素数

int arr[MAX] ;

int i = 0,j=0;

for (i = 0; i < num - 2; i++)//初始化数组[2,num]

arr[i] = i + 2;

while (arr[j]<=sqrt(num))//除数的范围

for (i = j + 1; i < num - 1; i++)

if (arr[i]%arr[j] ==0)//筛去arr[i]的倍数

arr[i] = 0;

j++;

while(!arr[j])//确定最小数

j++;

for (i = 0; i < num - 1; i++)

if (arr[i])

printf("%d\\t",arr[i]);

int main()

int num;

printf("请输入一个正整数:");

scanf("%d",&num);

if (num > 1)

printf("打印出所有的素数:");

print_prime(num);

else

printf("不存在小于等于%d的素数",num);

printf("\\n");

return 0;

    上面的代码有一个很明显的缺陷就是开辟空间过大,如何来解决这个问题呢?

    上述代码所开辟的空间为int型,占用4个字节,占用空间太多,可以构造一个bool型数组,bool型是一个基本的数据类型,占1个字节,以下标来存储数据,节省了75%的空间。

 优化

构造bool型数组,以下标来存储数据,每个数只占一个字节。

代码如下:

#include<stdio.h>

#include<stdbool.h>

#include<math.h>

#define MAX 1000  //定义数组的大小

void print_prime(int num)//prime表示素数

bool arr[MAX] ;

int i = 0,j=2;

for (i = 0; i <num ; i++)//初始化数组为真

arr[i] = 1;

while (arr[j]<=sqrt(num))//除数的范围

for (i = j + 1; i <= num ; i++)

if (i%j ==0)//筛去arr[i]的倍数

arr[i] = 0;

j++;

while(!arr[j])//确定最小数

j++;

for (i = 2; i <=num ; i++)//打印素数

if (arr[i])

printf("%d\\t",i);

int main()

int num;

printf("请输入一个正整数:");

scanf("%d",&num);

if (num > 1)

printf("打印出所有的素数:");

print_prime(num);

else

printf("不存在小于等于%d的素数",num);

printf("\\n");

return 0;

结果1:

请输入一个正整数:9

打印出所有的素数:2     3       5       7

请按任意键继续. . .

结果2:

请输入一个正整数:1

不存在小于等于1的素数

请按任意键继续. . .


本文出自 “岩枭” 博客,请务必保留此出处http://yaoyaolx.blog.51cto.com/10732111/1740043

以上是关于C语言新手 给定一段连续的正整数,请判断其中素数的个数的主要内容,如果未能解决你的问题,请参考以下文章

初识C语言之如何打印100~200之间的素数

C语言判断素数

c语言:实现对于给定的正整数N,依次打印出小于等于N的所有素数。两种方法及其优化

c语言编程:连续输入若干个正整数,求其和及其平均值,直到输入0结束.

c语言编程:连续输入若干个正整数,求其和及其平均值,直到输入0结束.

c语言:实现对于给定的正整数N,依次打印出小于等于N的所有素数。两种方法及其优化