1. 程式人生 > >問題:求n以內的所有素數。要求給出自然語言描述的演算法,並且實現演算法。事先分析演算法的時間複雜度和空間複雜度。/*如果錯誤或相關改進的歡迎提出,謝謝!*/

問題:求n以內的所有素數。要求給出自然語言描述的演算法,並且實現演算法。事先分析演算法的時間複雜度和空間複雜度。/*如果錯誤或相關改進的歡迎提出,謝謝!*/

/*2018.10.20上傳,該貼還有部分需要完善,比如2輸不出,還有許多可以優化的地方,未完,待更~~*/

#include <stdio.h> #include <math.h> #include <time.h> void prime(int n); int main() {     unsigned int n;     clock_t start, end;     start = clock();     printf("請輸入你要查詢素數的最大範圍:");     while (!scanf_s("%d", &n))     {         fflush(stdin);//清理快取         printf("請輸入合法字元,請重新輸入:");     }     printf("以下為2~%d的所有素數\n", n);     prime(n);     end = clock();     printf("耗時%d毫秒\n", end - start);     system("pause");     return 0; } void prime(int n) {     int i, j;     for (i = 3; i <= n; i += 2)     {         for (j = 2; j <= sqrt(i); j++)         {             if (i%j == 0)             {                 break;             }         }         if (j>sqrt(i))//輸出素數,因為一個素數開根號會小於這個數與之右相臨的數         {             printf("%8d", i);         }     } } /*2018.10.22晚所寫*/

自然語言描述的演算法:

目標:求n以內的所有素數

素數的定義:只能被1和它自己整除,而不能被其他自然數整除的數,1除外

涉及的相關原理:一素數的的最大公因數必定小於這個素數的算數開平方根        

一、從鍵盤內讀入2~n範圍內的整數;

二、再篩選掉2~n以內的偶數;

三、篩除的2又為素數,因此進行單獨輸出;

四、從3~n以內的奇數開始迴圈篩選,如這個數能被從2到這個數的算數開平方根整除,則跳出迴圈;如果不能(判斷條件:因為一個素數開根號會小於這個數與之右相臨的數),則輸出這個數,即為素數;

時間複雜度:因為首先n以內的偶數先排除,剩n/2個數(n>2)),從3

開始,因此第一次迴圈理論上執行(n-2)/2次,第二次迴圈從2開始至√n,執行√n-1次,執行次數為(n-2)*( n-1)/2因為數量級涉及至n,因此程式中其語句執行次數都基本上可以忽略,所以才程式的時間複雜度為O(n^(3/2));

空間複雜度:因為在篩選當中之運用到了i,j兩個變數,因此空間複雜度為O(1);

#include <stdio.h>

#include <math.h>

#include <time.h>

void prime(int n);

int main()

{

    unsigned int n;// 無符號整型範圍為 4394967295,輸入該數的最大範圍

    clock_t start, end;//定義初始時間,利用clock函式計算程式執行時所花的時間長短

    start = clock();

    printf("請輸入你要查詢素數的最大範圍:");

    while (!scanf_s("%d", &n))//運用scanf函式的返回值,如果輸入的不是一個數,則返回0.反之,則返回1

    {

         fflush(stdin);//清理快取

         printf("請輸入合法字元,請重新輸入:");

    }

    printf("以下為2~%d的所有素數\n", n);

    prime(n);

    end = clock();

    printf("耗時%d毫秒\n", end - start);

    system("pause");

    return 0;

}

void prime(int n)

{

    int i, j,isPrime=2;//isPrime=2,對2進行單獨輸出

if(n==2)

         printf("%8d",n);

    for (i = 3; i <= n; i += 2)//篩除所有的偶數

    {

         printf("%8d", isprime);

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

         {

             if (i%j == 0)

             {

                  break;

             }

         }

         if (j>sqrt(i))//輸出素數,因為一個素數開根號會小於這個數與之右相臨的數

         {

             printf("%8d", i);

         }

    }

}

事後統計:1000以內用時1478ms左右;

                   10000以內用時2000ms左右;

                   20000以內用時2500ms左右;

                   100000以內用時7000ms左右;

                         理論上,這個數小於等4394967295,都可對其進行測試

以下為1000以內的素數:

 3       5       7      11      13      17      19      23      29      31      37      41      43      47      53      59      61      67      71      73      79      83      89      97     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