這是一個位掩碼 - 對於30個可能爲素數的8個值中的每一個,都有一位,所以每30個數字有8位。要將所有素數列表爲10^6,您需要8 * 10^6/30 = 2666667位= 33334個字節。
爲了解釋爲什麼這是一個好方法,你需要看看明顯的選擇。
一個更幼稚的方法就是使用位掩碼。你需要一百萬位,125000字節。
你也可以存儲素數的值。高達1000000,這些值適合20位,並且有78498個素數,所以這給出令人失望的1569960位(196245字節)。
另一種方法 - 儘管查找素數不太有用 - 但是要存儲每個素數和下一個素數之間的差異。低於一百萬,這符合6位(只要您記得那時素數都是奇數,所以您只需要存儲偶數差異並因此可以丟掉最低位),即470998位== 58874字節。 (你可以通過計算你需要跳轉多少個mod-30插槽來削減另外一點)。
現在,除了30 = 2 * 3 * 5之外,沒有什麼特別的30,所以這個查找實際上是在走你在開始之後立即通過Eratosthanes篩的掩模表示。你可以使用2 * 3 * 5 * 7 = 210,然後你必須考慮+ - 1,11,13,17,19,23,29,31,37,41,43,47,53, 59個,61個,67個,71個,73個,79個,83個,89個,97個,101個,103個,48個值。如果你用7塊30塊這樣做,你需要7×8 = 56位,所以這是一個小小的改進,但呃...幾乎沒有值得的麻煩。
所以這是更好的技巧之一,用於緊湊地存儲合理的小素數。有趣的是,如果素數隨機出現(但實際出現的相同數字達到1000000),則存儲在1和10^6之間數字的素數中的信息量將是〜0.397比特因此,在天真的信息理論假設下,你會認爲存儲第一百萬個素數的最好方法是使用1000000 * 0.397位或49609字節。)
應該是「每一個除了2,3和5之外的素數可以表示爲...「? – MatrixFrog 2010-04-10 17:00:35
@MatrixFrog:當然,但是你的「解壓程序」只會在輸出壓縮數據之前輸出這3個數據。 – 2010-04-10 18:54:05