[計算機漫談]算法運行時間估計及素數判斷算法


    大家好!這是我的第一篇博文,謝謝大家的支持!

   (一)算法運行時間估計

   估計某個算法的時間復雜度需要一些數學定義,如   T(N) = O(fn),表示T(N)的增長率小於等於fn;    T(N) = Ω(fn),表示T(N)的增長率大於fn;    T(N) = θ(fn),表示T(N)的增長率等於fn;    T(N) = o(fn),表示T(N)的增長率小於fn. 我們一般考察O,即大O,時間上界.一個算法運行的時間進行估計,以便我們更好的了解程序設計與運行的優化方法.

   

  估計法則1:

       如果T1(N) = O(fn),t2(N) = O(gn),則有 T1(N)+T2(N) = max(O(fn),O(gn)) ,T1(N)*T2(N) = O(fn*gn)

 

   估計法則2(循環):

      一次循環的運行時間至多是循環體內語句運行時間乘以循環次數;嵌套循環為循環體內語句運行時間乘以各層循環次數之積.

 

   估計法則3(順序結構):

      順序結構運行時間等於各條語句運行時間之和.

 

   估計法則4(分支結構):

     分支結構運行時間不會大於分支中運行時間最長的那個分支體.

 

   估計法則5(對數):

     對數形式一般出現在 一個算法用常數時間將問題大小削減一半(或者有形如k *= 2的形式), 如二分查找

 

  綜合以上法則,我們就可以分析出某個具體算法的時間上界

 

 例:分析運行時間

    

1 Value = 0; 2    for( i= 1; i < N; i++) 4      for( j = 1;j < i*i; j++) 6          for( k = 0; k < j; k++) 8                    Value++;

 

 

 

     Value++的運行時間為常數階,第一層循環次數為N;第二層循環次數i*i與N2   有關,因為i與N有關.同理第三層循環次數j與N2 有關.則N*N2 *N2=N5,即O(N5)

 

   (二)素數判斷算法

    在程序設計的學習過程中,判斷一個數是否為素數的算法相信大家都非常熟悉了,這里與大家復習一下並提出更好的方案.

    首先,什么是素數.素數就是除了1和它本身外,沒有其他因數的正整數.啊,將n從2除到√n,這是我的,相信也是很多人的第一想法.那么有沒有更好的方案吶?讓我們從頭開始.

 

    嘗試1:

1 bool isPrime(int n){ 2 if(n <= 1) 3       return false;                              //1以及非正數不可能為素數,函數返回
4 for(int i = 2; i < n; i++){                  //從2開始找到n-1
5      if(n%i == 0) 6       return false;                   //被整除代表有其他因數,這不是素數,函數返回
7 } 8       return true;                               //檢驗完畢,為素數,函數返回
9 }

 

  這是最原始的算法,根據素數定義.容易得到,最壞情況比較要進行n-2次,時間復雜度為O(n).對於判斷一個大數的情況,顯然費時.

 

  嘗試2:

1 bool isPrime(int n){ 2  if(n <= 1) 3       return false; 4 for(int i = 2; i <= (n/2); i++){ 5      if(n%i == 0) 6       return false; 7 } 8       return true; 9 }

 

 因為一個數的因數總是成對出現(如2*3=6,2和3都是6的因數),且按這個數的中值對稱分布,因此只需要算到這個數的一半就行了.顯然,循環比較次數比嘗試1少,但時間復雜度仍為O(n).

 

 嘗試3:

1 bool isPrime(int n){ 2  if(n <= 1) 3      return false; 4 for(int i = 2; i <= sqrt(n); i++){ 5    if(n%i == 0) 6      return false; 7 } 8      return true; 9 }

 

這個方法相信大家非常熟悉,也是最容易想到的.依據是若n有因數a和b,即n=a*b,那么必有一個因數位於2到√n之間,又因因數對稱且成對出現,那么檢驗范圍從2到√n就行了(我們當然可以檢驗√n到n-1),時間復雜度為O(√n)

 

嘗試4:

 1 bool isPrime(int n){  2  if(n == 2)                                 //2是偶數中唯一的素數
 3     return true;  4  if(n <= 1 || n%2 == 0)           //除了2外,所有偶數都不是素數,至少有因數2
 5     return false;  6 for(int i = 3; i <= sqrt(n); i+=2){  7   if(n%i == 0)  8     return false;  9 } 10     return true; 11 }

 

注釋說的很清楚了.這個算法比嘗試3進一步減少了檢驗比較次數,時間復雜度為O(√n)

除了上面這些基本嘗試(特別是嘗試4,比較不錯了)外,還有其他算法,如使用素數表的拉賓米勒測試等,還有些算法就需要很多的數學知識了,額.

書籍推薦:

 

 

謝謝大家!轉載請注明出處,謝謝合作!


免責聲明!

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



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