C语言之判断质数算法

今天学校OJ的一题判断是质数和合数。

首先我们要弄明白质数和合数的概念:质数就是除了本身和1以外没有其他因数的数,合数就是除了本身和1以外还有其他因数的数。注意:1既不是质数也不是合数

明白了概念,下面在考虑题目本身。

1、输入 :输入待判断的数n。(额外要求 2<=n<10000,且可连续输入)。

2、输出:质数:’Yes‘ ,合数:’No‘。

 

那么如何判断是否为质数和合数呢?

质数就是除了本身和1以外没有其他因数的数。

那么就只用遍历2~n-1中的数,让他们逐个与n取余。只要其中一个数可与n取余得0,即为可整除,即可判断不是质数,是合数。

如下算法:(需注意的是2在判断时需额外判断,因为2~n-1会报错。

 1 #include
 2 int  main()
 3 {
 4     int n;
 5     while(scanf("%d",&n)!=EOF)
 6     {
 7         
 8         if (2<n<10000)
 9         {
10             int flag=1;
11             for (int i=2;i<=n-1;i++)
12             {
13                 if (n%i==0) 
14                 {flag=0; 
15                 break;}
16             }
17             if (flag) printf("Yes\n");
18             else  printf("No\n") ;
19         } 
20         else if (n==2) printf("Yes\n");
21         else printf("输入错误\n");
22     }
23     return 0;
24 }

以上算法的复杂度是O(n),最差的情况下运行n次。如需改进,我们可以在整除的地方思考一下,要判断n在2~(n-1)处是否能整除,而在大于n/2时无论其取何值,都不可能使n被整除,所以只要判断2~n/2之间的数是否能整除n即可。

代码如下:

 1 #include
 2 int  main()
 3 {
 4     int n;
 5     while(scanf("%d",&n)!=EOF)
 6     {
 7         
 8         if (2<n&&n<10000)
 9         {
10             int flag=1;
11             for (int i=2;i<=n/2;i++)
12             {
13                 if (n%i==0) 
14                 {flag=0; 
15                 break;}
16             }
17             if (flag) printf("Yes\n");
18             else  printf("No\n") ;
19         } 
20         else if (n==2) printf("Yes\n");
21         else printf("输入错误\n");
22     }
23     return 0;
24 }

 实际上我们可以证明,如果n不是素数,那么n必须有一个大于1且小于或者等于√n。证明过程:

因为n不是素数,所以会存在两个数p和q,满足n=pq且1<p≤q。注意到n=√n*√n。p必须小于等于√n。

所以代码可改为如下:

 1 #include<stdio.h>
 2 #include<math.h>
 3 
 4 int  main()
 5 {
 6     int n;
 7     while(scanf("%d",&n)!=EOF)
 8     {
 9         
10         if (3<n&&n<10000)
11         {
12             int flag=1;
13             for (int i=2;i<=(int)sqrt(n);i++)
14             {
15                 if (n%i==0) 
16                 {flag=0; 
17                 break;}
18             }
19             if (flag) printf("Yes\n");
20             else  printf("No\n") ;
21         } 
22         else if (n==2||n==3) printf("Yes\n");
23         else printf("输入错误\n");
24     }
25     return 0;
26 } 

这就是今天get到的一个算法。

此外,通过我的思考我解决了一个我遇到的一个问题。在循环判断语句中,根据判断条件会进行循环判断,如果要待循环全部进行完进行一个总的判断,可设置一个标志变量记录。(就比如本题,要等所有在区间内的数全部测试是否能整除,才能判断是否为质数,这时可添加一个局部变量flag来记录每次循环判断的值并最终进行汇总)。

路漫漫~~~~

 

posted @ 2021-10-27 23:39  chanxe  阅读(1525)  评论(0编辑  收藏  举报