1. 程式人生 > >埃氏篩選與線性篩選求素數

埃氏篩選與線性篩選求素數

//埃氏篩選法 複雜度O(nlognlogn)
#include<bitset>
#include<map>
#include<vector>
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<stack>
#include<queue>
#include<set>
#define inf 0x3f3f3f3f
#define mem(a,x) memset(a,x,sizeof(a))

using namespace std;

typedef long long ll;
typedef pair<int,int> pii;

inline int in()
{
    int res=0;
    char c;
    while((c=getchar())<'0' || c>'9');
    while(c>='0' && c<='9')res=res*10+c-'0',c=getchar();
    return res;
}

const int N=2000010;
bool vis[N];
//bitset<N> vis;
int prime[150010];

int main()
{

   // vis.set();
   //多次求素數的話要初始化
    int p=1;
    prime[0]=2;
    for(int i=3;i<=N;i+=2)
    {
        if(!vis[i])
        {
            prime[p++]=i;
            for(int j=i*2;j<=N;j+=i)
            {
                vis[j]=1;

            }
        }
    }
    int n;
    while(~scanf("%d",&n) && n)
    {
        int i=0;
        while(prime[i]<=n)
        {
            printf("%d ",prime[i]);
            ++i;
        }
        putchar('\n');
    }

    return 0;
}


下面的是線性篩選演算法,與埃氏篩選相比,對於每個不是素數的數,這個演算法只把它篩一次,不會多次篩掉,而埃氏篩選會多次篩掉。

分別用它們算了一下一億以內素數的個數,埃氏篩選用時4-5秒的樣子,而這個不到兩秒。另外不知道為啥,用bitset代替bool陣列比較慢,

但是bitset顯著減少了記憶體使用。

#include<bitset>
#include<map>
#include<vector>
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<stack>
#include<queue>
#include<set>
#define inf 0x3f3f3f3f
#define mem(a,x) memset(a,x,sizeof(a))

using namespace std;

typedef long long ll;
typedef pair<int,int> pii;

inline int in()
{
    int res=0;
    char c;
    while((c=getchar())<'0' || c>'9');
    while(c>='0' && c<='9')res=res*10+c-'0',c=getchar();
    return res;
}
const int N=2000010;
//bitset <N>vis;
bool vis[N];
int prime[150000];
int main()
{
    int p=-1;
    //如果多次求素數的話要每次初始化vis
    for(int i=2;i<=N;i++)
    {
        if(!vis[i])prime[++p]=i;
        for(int j=0;j<=p && prime[j]*i<=N;j++)
        {
            vis[prime[j]*i]=1;
            if(i%prime[j]==0)break;
        }
    }
    int n;
    while(~scanf("%d",&n) && n)
    {
        int i=0;
        while(prime[i]<=n)
        {
            printf("%d ",prime[i]);
            ++i;
        }
        putchar('\n');
    }
    return 0;
}


相關推薦

篩選線性篩選素數

//埃氏篩選法 複雜度O(nlognlogn) #include<bitset> #include<map> #include<vector> #include<cstdio> #include<iostream>

篩法+線性篩法+杜教篩+min25篩總結

埃氏篩法 這個篩法是最樸素的篩法了,可以在 O(nloglogn) O ( n l o

關於用篩選素數python程式碼的一些理解

原始碼 來自廖雪峰-filter 演算法描述參考原文。 程式碼塊如下: def _odd_iter(): # 生成一個無限序列的奇數Generator z = 1 while True: z = z+2 yield z def

使用拉托色尼篩選法(the Sieve of Eratosthenes)在一定範圍內素數及反素數(Emirp)

Programming 1.3 In this problem, you'll be asked to find all the prime numbers from 1 to 1000. Prime numbers are used in allkinds of circumstances, particu

【演算法】3.Eratosthenes篩選尤拉篩選素數

Eratosthenes篩法 1.原理 一個合數可以分成幾個素數的和,如果把素數(最初只知道2)的倍數全都去掉,剩下的就都是素數了 2.思路分析 去除0,1(既不是素數又不是合數) 找到佇列中最小的素數,刪除其倍數 3.程式碼實現(只給出了函

演算法:拉托色尼篩選素數(Python和Java)

來自百度百科–埃拉托色尼篩選法: (1)先把1刪除(現今數學界1既不是質數也不是合數) (2)讀取佇列中當前最小的數2,然後把2的倍數刪去 (3)讀取佇列中當前最小的數3,然後把3的倍數刪去 (4)讀取佇列中當前最小的數5,然後把5的倍數刪去 (5)讀

拉托色尼篩選法-素數

// 埃拉托色尼篩選法- 求素數 void getprimes(int n) { int result[n]; for (int i = 0; i < n; ++i) { result[i] = i + 1; }

HDU Largest prime factor(拉托色尼篩選素數模板法改動)

題意:給你一個數,求它這個數的最大素因子在素數表的第幾位 思路:剛開始思路有一點錯誤,看錯誤程式碼 錯誤程式碼: #include <iostream>0 #include <cs

篩選素數

return include main 技術 ret printf int images ima C語言 #include <stdio.h>#include <math.h>int main(){int i,j,a[100],N;scanf("

篩選法<素數表>

spa 素數 表示 fine define pri bsp 遍歷 數組 如果題目的數據規模較大,常規地逐個判斷素數的方法行不通,可以使用篩選法進行預處理,將所有素數一次性求出並存入數組中。 篩選法求素數的主要思想如下: (1)將1~N的所有數都標記為素數,0表示素數,1表

篩法(n以內有多少個素數

cin algorithm memset fin lse mod pre 判斷 end 題目大意:給定整數n,請問n以內有多少個素數 思路:想必要判斷一個數是否是素數,大家都會了,並且可以在O(根號n)的復雜度求出答案,那麽求n以內的素數呢,那樣求就顯得有點復雜了,下面看一

用“篩法”2~100以內的素數

用“埃氏篩法”求2~100以內的素數。2~100以內的數,先去掉2的倍數,再去掉3的倍數,再去掉5的倍數,……依此類推,最後剩下的就是素數。 請上傳壓縮後的原始碼檔案,程式碼可直接並正確執行; 請注意程式碼風格:類名、變數名的命名,以及必要註釋等等; 以防上傳失敗,請同時把程式碼貼到

Numpy攻略:用篩選

埃氏篩:篩選質數的一種演算法,用迭代的方式識別出已經找到的質數的倍數,能高效地篩選出小於一千萬的質數。讓我們去試著尋找10001個質數。 具體步驟如下: 1.建立一個連續的整數列表:用arange函式 2.篩選出p的倍數 完整程式碼如下圖: import numpy

數論_篩法(區間內多少素數

埃拉託斯特尼(公元前276—公元前194) 埃拉託斯特尼是古希臘著名的數學家、地理學家、天文學家。他先在亞歷山大港學習,後又轉至雅典。公元前236年,托勒密三世指定他為亞歷山大圖書館的圖書管理員和館長。他跟阿基米德是好朋友。埃拉託斯特尼的主要貢獻包括: 埃拉託斯特尼篩法:尋找素數的方法。 地理常數測量:

caioj 1157 線性篩選素數

注意這道題開得非常大,有2*1e7 自己可以養成一種習慣,如果資料是很容易的話,可以自己手動輸入極限資料來測試自己的程式 #include<cstdio> #include<alg

用“篩法”2~10000以內的素數。2~100以內的數,先去掉2的倍數,再去掉3的倍數,再去掉5的倍數,……依此類推,最後剩下的就是素數

package Homework; public class Test2 {public static void main(String[] args){       int[] a=new int[10000]; for(int i=0;i<a.length;i++){  //初試化陣列,a[0]=2

篩選素數演算法

篩選法生成質數表(素數表)的基本思想如下: 假設有一個數組存放整數2 ~ N,如下所示: 首先將2的倍數篩去(實際操作時可以將陣列對應的值設定為0),得到: 然後將3的倍數篩去,得到: 再一次將5的倍數篩去,7的倍數篩去,11的倍數篩去......

素數個數(篩法和尤拉篩法)

求1——n的素數的個數,有以下三種方法: 普通的O()演算法: #include<iostream> #include<cstdio> #include<cmath> using namespace std; bool isprim

篩選素數 java

思路:在一個boolean型別的陣列中 ,從第二個開始遍歷,將2的倍數置為false,3的倍數置為false。例項說明一下: 求0-10的素數,定義陣列boolean b[]=boolean[11];

篩法素數-Python

def _not_divisible(n): #是否整除 return lambda x: x%n > 0 def _odd_iter(): #建立奇數序列 n = 1 while True: n += 2 y