1. 程式人生 > >【演算法】尋找1000000000(十億)內素數並統計個數

【演算法】尋找1000000000(十億)內素數並統計個數

已優化到 22 秒內,不知道世界最快演算法在同樣環境下執行速度是多少,下面貼出程式碼,C#

using System;

namespace prime
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime dt = DateTime.Now;
            int n = 1000000000;
            Console.WriteLine(Get_Prime_Count(n));
            DateTime dt2 = DateTime.Now;
            Console.WriteLine(dt2-dt);
        }
        static int Get_Prime_Count(int n)
        {
            int count = 0;  //後面用於統計素數個數
            bool[] big = new bool[n + 1]; //用於標記是否為素數

            int sl = 2 * 3 * 5 * 7 * 11 * 13 * 17 * 19;
            bool[] small = new bool[sl + 1]; //用於篩選掉13及以內質數的倍數

            int i;

            for (i = 2; i <= sl; i += 2)
                small[i] = true;
            for (i = 3; i <= sl; i += 3)
                small[i] = true;
            for (i = 5; i <= sl; i += 5)
                small[i] = true;
            for (i = 7; i <= sl; i += 7)
                small[i] = true;
            for (i = 11; i <= sl; i += 11)
                small[i] = true;
            for (i = 13; i <= sl; i += 13)
                small[i] = true;
            for (i = 17; i <= sl; i += 17)
                small[i] = true;
            for (i = 19; i <= sl; i += 19)
                small[i] = true;

            //以下通過拷貝去掉big中所有13及以內質數的倍數
            int remainder = n % sl; //餘數
            int p = 1;
            int q = p + n - remainder;
            while (p < q)
            {
                Array.Copy(small, 1, big, p, sl);
                p += sl;
            }
            if (remainder > 0)
            {
                Array.Copy(small, 1, big, p, remainder);
            }

            //下面這幾個不能漏掉
            big[2] = false;
            big[3] = false;
            big[5] = false;
            big[7] = false;
            big[11] = false;
            big[13] = false;
            big[17] = false;
            big[19] = false;

            int sqrt = (int)Math.Sqrt(n);//平方根
            int step,j;
            sqrt -= 2;
            for (i = 23; i <= sqrt; i += 6)
            {
                if (!big[i])
                {
                    step = i * 6;
                    for (j = i * i; j <= n; j += step)
                    {
                        big[j] = true;
                    }
                    for (j = i * i + 2 * i; j <= n; j += step)
                    {
                        big[j] = true;
                    }
                }
                int mm = i + 2;
                if (!big[mm])
                {
                    step = mm * 6;
                    for (j = mm * mm; j <= n; j += step)
                    {
                        big[j] = true;
                    }
                    for (j = mm * mm + 4 * mm; j <= n; j += step)
                    {
                        big[j] = true;
                    }
                }
            }

            //統計素數個數
            for (i = 7; i <= n-4; i += 6)   //100010  從7開始
            {
                if (!big[i]) count++;
                if (!big[i+4]) count++;
            }
            count+=3; //還有2、3、5
            return count;
        }
    }
}


相關推薦

演算法尋找1000000000素數統計個數

已優化到 22 秒內,不知道世界最快演算法在同樣環境下執行速度是多少,下面貼出程式碼,C# using System; namespace prime { class Program { static void Main(string[]

JMeter學習JMeter函數學習

blog 自動 當前 3.2 add 函數的調用 瀏覽器 con 保存 JMeter函數是一些能夠轉化在測試樹中取樣器或者其他配置元件的域的特殊值。一個函數的調用就像這樣:${_functionName(var1,var2,var3)},-functionName匹配函數名

JMeter學習JMeter測試Java

sets interval permsize int 文件 不同 時間 結果 argument 實例: 服務為:將輸入的兩個參數通過IO存入文件; 1、打開MyEclipse,編寫Java代碼 服務: package test; import java.io.F

2018.12.07LOJ6019尋找LCM組合數學

傳送門 解析: 有點小騷的操作啊。。。 很是妙妙的一道題,最開始教練是抱著讓我卡常的心態做的。然後根本優化不動。。。 一看AC了的程式碼。。。WOC真的很妙妙。 思路: 首先不要想

PythonMatplotlib畫圖——箱線圖

資料描述 引數介紹 plt.boxplot(x, notch=None, sym=None, vert=None, whis=None, positions=None, widths=None, patch_arti

C語言天天練restrict關鍵詞

引言:在核心的系統呼叫函式裡,常常遇到函式的引數使用restrict限定詞限定的情況,以下就對該關鍵詞做個總結。 1、restrict關鍵詞是C99特性才加入的,因此在編譯使用含有該限定詞的程式時,一定要在後邊加入-std=c99的標誌,使得gcc能夠支援c99標準。 2

PP生產訂單入門介紹

一、重大確認 重大確認:比如有10、20、30三個工序,30設定成了重大確認,當你做30報工的時候系統會自動對10和20也做報工。 設定方法:工序設定裡面的”控制碼“。 然後我們使用事務程式碼CO11直接對工序0030做確認,可以發現”重大事件“這裡是預設勾選的。

PP生產訂單入門介紹

這一講我們主要來介紹一下生產訂單的收貨。 Goods Receipt 成品入庫: 下圖則是收貨後會產生哪些影響。 1、啟用WMS模組的話會產生一個貨倉轉移需求。 2、列印收貨單。 3、影響庫存數量及價值。 4、產生物料文件。 5、產生財務文件。 6、產

演算法尋找第k大的數

目錄: 1、引子 2、排序解決法 3、類快排解法 4、最小堆解法 1、引子 日常編碼中,常見遇到這樣的問題,“尋找最大的數”,此問題非常容易,可暴力直接遍歷找出,也可使用分冶策略找出最大值(詳見分冶演算法)。 本文中需要尋找第k大的數,筆者目前想到3個方法可解決它。 2、排序解決法

尋優演算法交叉驗證Cross Validation引數尋優的python實現:多引數尋優

【尋優演算法】交叉驗證(Cross Validation)引數尋優的python實現:多引數尋優 一、網格搜尋原理 二、網格搜尋+交叉驗證用於多引數尋優的python實現 1、訓練模型及待尋優引數 2、直接迴圈巢狀實現網格搜尋 + cros

尋優演算法交叉驗證Cross Validation引數尋優的python實現:單一引數尋優

【尋優演算法】交叉驗證(Cross Validation)引數尋優的python實現:單一引數尋優 一、交叉驗證的意義 二、常用的交叉驗證方法 1、Hold one method 2、K-flod CV 3、Leave-One-Ou

排序演算法氣泡排序Bubble Sort

一、簡介 氣泡排序(Bubble Sort)也是一種簡單直觀的排序演算法。它重複地走訪過要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。走訪數列的工作是重複地進行直到沒有再需要交換,也就是說該數列已經排序完成。這個演算法的名字由來是因為越小的元素會經由交換慢慢“浮”到數列的頂端。 二、

C語言天天練字元/字串輸入函式fgetc、fgets、getc、getchar和gets

#include <stdio.h> intfgetc(FILE *stream); char *fgets(char *s, int size, FILE *stream); int getc(FILE *stream); int getchar(void);

51nod 尋找分數數學

基準時間限制:1 秒 空間限制:131072 KB 分值: 160 給出 a,b,c,d, 找一個分數p/q,使得a/b < p/q < c/d,並且q最小。例如:1/3同1/2之間,符合

演算法Trie數字首樹/字典樹簡介及Leetcode上關於字首樹的題

前幾天同學面今日頭條被問到了Trie樹,剛好我也對於Trie樹這種資料結構不是很熟悉,所以研究了一下字首樹,然後把Leetcode上關於字首樹的題都給做了一遍。 Leetcode上關於字首樹的題有如下: Trie簡介 Trie樹,又稱單詞查詢樹

Mybatis深入淺出Mybatis——逆向工程

一、前言       前一篇部落格中,小編向大家介紹了一下Mybatis和hibernate的對比,在這一篇部落格說說mybatis的逆向工程,展示一下,一個非常讓你驚訝的技術,只要你有一個數據庫,你的持久層,你的D層從此不用你自己手寫了。 二、什麼是逆向工

資料結構與演算法——連結串列Linked List

## 連結串列(Linked List)介紹 > 連結串列是有序的列表,但是它在記憶體中是儲存如下: > > ![](http://itfxsen.oss-cn-chengdu.aliyuncs.com/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8E%E7%AE%

POJ3074Sudoku DLXDancing Links

puts struct pre i++ 能夠 ring include 為什麽 處理 數獨就要DLX,不然不樂意。 數獨的DLX構造:9*9個點每一個點有9種選擇,這構成了DLX的729行,每行、列、陣有限制,均為9行(/列/陣),然後每行(/列/陣)都有九

luogu P3388 模板割點割頂

true algorithm fin can clas light fine sca 表示 題目背景 割點 題目描述 給出一個n個點,m條邊的無向圖,求圖的割點。 輸入輸出格式 輸入格式: 第一行輸入n,m 下面m行每行輸

洛谷P3388 模板割點割頂

span iostream 模板 pri add ++ 割點 logs () 表示割點模板很難理解。。。。但是呢,可以將整個圖用深搜來一步步遞歸。。 dfn[x]<=low[tmp] && x!=mr的點就++;完畢。。。。PS:小心第一個節點。。。