一種無雙篩現象的乘篩質數法

以往的質數篩都採用除篩法,通過逐個測試 [3,N] 對 [2, \sqrt N] 的可除性來確認一個數是不是質數。
衆所周知,計算機除法是一系列減法的組合,運算速度較慢。
當計算機具有足夠大的內存時,可以採用乘篩法,方法是先定義一個一維旗標數組,當做一條有限長的紙帶,下標 [1,N] 的每個元素對應一個自然數的狀態,從I = 2開始逐個篩去因數的倍數I \times J (J \geqslant 2),將被篩數所在的旗標置1(打孔),表示已經被驗證爲合數,直到因數 [2, \sqrt N] 全部被篩完,這時紙帶上未被打孔的就是質數。然後枚舉旗標數組,將未被標記爲合數的數字作爲質數顯示出來,例如:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

(未完待續)

#INCLUDE "VBCOMPAT.BI"

'定義紙帶長度
CONST PAPER_LEN AS INTEGER = 121

'定義合數指示旗標
DIM FLAG() AS INTEGER
DIM FLAG_TMP() AS INTEGER

'定義循環變量
DIM I AS INTEGER
DIM J AS INTEGER
DIM N AS INTEGER
DIM A AS DOUBLE
DIM B AS DOUBLE
DIM K AS INTEGER

REDIM FLAG(PAPER_LEN * 2 + 1)
REDIM FLAG_TMP(PAPER_LEN * 2 + 1)

'劃掉第一個數
FLAG(1) = 1

N = PAPER_LEN

PRINT "PRIME v0.01"
PRINT "PAPER_LEN = "; N
PRINT "SQR(N) = "; SQR(N)

A = NOW
PRINT "BEGIN = "; FORMAT(A, "yy/mm/dd hh:mm:ss")

'劃掉偶數
J = 2 
I = 2
K = 1
DO WHILE I < N
  I = I + J
  FLAG(I) = 1
  K = K + 1
LOOP

FOR I=3 TO SQR(N) STEP 2
  IF FLAG(I) = 0 THEN
    FOR J=I TO N/I STEP 2
      IF FLAG(J) = 0 THEN
        FLAG_TMP(I*J) = 1
        K = K + 1
      END IF
    NEXT J
    FOR J=I TO N STEP 2
      IF FLAG_TMP(J) = 1 THEN
        FLAG(J) = 1 : FLAG_TMP(J) = 0
      END IF
    NEXT J
  END IF
NEXT I

FOR I=1 TO N
  IF FLAG(I) = 0 THEN
    PRINT I,
  END IF
NEXT I

B = NOW
PRINT "OPERATIONS = "; K
PRINT "END = "; FORMAT(B, "yy/mm/dd hh:mm:ss")

END

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章