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來記錄每次循環判斷的值並最終進行匯總)。

路漫漫~~~~

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM