程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 篩選法求質數

篩選法求質數

編輯:關於C語言

    傳統的解法就是利用"一個數 n 如果是合數,那麼它的所有的因子不超過sqrt(n)"這一性質來求解,時間復雜度為o(n*sqrt(n)),顯然當n很大時這種方法便不太適用。

           (i=; i<MAX; ++         (j=; j<=()sqrt(i); ++             (i%j ==                            (j > (             printf(  }
 
                prime[] =      prime[] =      count =      (i=; i<MAXNUM; i+=         (i%             (j=; prime[j]<=()sqrt(i); ++                 (i%prime[j] ==                                    (prime[j] > (                 prime[count++] =       (i=; i<count; ++         printf( }
上面是本人根據題意的解法,下面是作者的解法。  
               gap =         count =         may_be_prime =             prime[] =       prime[] =       prime[] =        (prime[count] <           may_be_prime +=           gap =  -            (i = ; prime[i]*prime[i] <= may_be_prime; i++                 (may_be_prime % prime[i] ==                                  (prime[i] > (                prime[count++] =        (i = ; i < count; i++           printf(  }

 
                (i=; i<MAXSIZE; ++         (i!= && i%==             prime[i] =         
             prime[i] =      (i=; i<=()sqrt(MAXSIZE); i+=                      (j=i+i; j<MAXSIZE; j+=                 prime[j] =        (i=; i<MAXSIZE; ++                      printf(  }
上面應該是最常見的篩選法求質數的程序,在初始化數組時將2的倍數設為了NO,這樣做是為了簡化程序。   版本二:
                (i=; i<MAXSIZE; ++         (i!= && i%==             prime[i] =         
             prime[i] =      (i=; i<=()sqrt(MAXSIZE); i+=                      (j=; j<=MAXSIZE/i; ++                 prime[i*j] =    
     (i=; i<MAXSIZE; ++                      printf(  } 
版本二與版本一原理一樣,版本二的可讀性更好。   版本三(優化):
       size = (MAXNUM - ) /  +                     (i=; i<size; ++         prime[i] =      (i=; i<size; ++                      key = i + i +             (j=key+*i*i+*i; j<size; j+=                 prime[j] =        printf(,     (i=; i<size; ++                      printf(,*i+  }
這裡的程序,prime[i]不再表示i為質數式合數,而表示2i+3為質數式合數,如果prime[i] = OK,則2i+3為質數,否則為合數。這樣做有什麼好處?因為所在的質都是奇數,2i+3能表示所有的質數(2除外),這樣做一方面減少了數組的空間,如需找出99以內的質數,用普通的篩選法則需定義一個100個長度的數組prime[100],而使用上面的程序只需定義一個(99-3)/2+1=49個長度的數組。空間個減少了一半。另一方面這做使得得到的質數全為奇數,直接排除了所有的偶數,提高了效率。程序中for(j=key+i;j<MAXSIZE/2-1;j+1=key){}這個for循環的作用是排除所有非質數,它是通過排除所有質數的奇數倍來排除奇數中的合數.具體操作如下,首先,確定一個質數2i+3,然後將2i+3的奇數倍對應的i值設為NO,如3(2i+3)為合數,則6i+9 = 2x+3,x=3i+3,於是將prme[3i+3]設為NO, 同理5(2i+3)=10+15=2x+3,x=5i+6,將prime[5i+6]設為NO。其中考慮到質數為5時會重復排除15(在3的時侯已經排除了),所以for循環中j=key+2*i*i+4*i,即從(2i+3)^2開始排除,而不是3(2i+3),為什麼3 5 7 9 11 ... ...中的素數n的倍數(奇數)要從n開始? 就是說從1開始和從n開始的效果是一樣,或者說n以前的奇數乘n都可以等於n以前(比n小的)素數的更大(比n大的)奇數倍數。由於n是奇數,可以設n以前(比n小的)的奇數為n-2i,比n大的奇數為n+2j;那麼我們的任務就是,證明n*(n-2i)可以等於m*(n+2j),其中m為小於n的素數,i、j都是正整數。即n(n-m)=2mj+2ni。這有變成證 明n-m是偶數,這是顯然的,兩個奇數之差必然是偶數。  

版本四(優化):

            size = (MAXNUM-)/+          (i=; i<size; ++         prime[i] =       (i=;i<size;i+=         (prime[(i-)/              (j=i*i;j<MAXNUM;j+=i<<                 prime[(j-)/] =       printf(,       (i=;i<size;++                       printf(, (i<<)+  } 
  版本五(線性篩選)
                     count =      (i=; i<MAXNUM; ++         is_prime[i] =       (i=; i<MAXNUM ; ++         (is_prime[i] ==              prime[count++] =          (j=; j<count && (i*prime[j]) < MAXNUM; ++             is_prime[i*prime[j]] =              (i % prime[j] == )        (i=; i<count; ++         printf(  }

         

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved