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语言:实现对于给定的正整数N,依次打印出小于等于N的所有素数。两种方法及其优化
c语言编程:连续输入若干个正整数,求其和及其平均值,直到输入0结束.