C 找質數(素數)厄拉多塞篩法

2021-07-10 05:00:36 字數 4775 閱讀 3923

c#找質數(素數)厄拉多塞篩法

質數(prime number)又稱素數,有無限個。指整數在乙個大於1的自然數中,除了1和此整數自身外,沒法被其他自然數整除的數。換句話說,只有兩個正因數(1和自己)的自然數即為素數(除了1和它本身以外不再有其他的因數)。根據算術基本定理,每乙個比1大的整數,要麼本身是乙個質數,要麼可以寫成一系列質數的乘積,比1大但不是素數的數稱為合數。1和0既非素數也非合數。最小的質數是2。

using system;

using system.collections.generic;

using system.linq;

using system.text;

using system.threading.tasks;

using system.diagnostics;

ms",s.elapsedmilliseconds);

s.reset();

s.start();

primenumber.find2();

s.stop();

system.console.writeline("watch: ms", s.elapsedmilliseconds);

s.reset();

s.start();

primenumber.find3();

s.stop();

system.console.writeline("watch: ms", s.elapsedmilliseconds);

s.reset();

s.start();

primenumber.find4();

s.stop();

system.console.writeline("watch: ms", s.elapsedmilliseconds);}}

public

class primenumber

\t", n);}}

system.console.write("count: \n", count);

}/*演算法的時間複雜度是o(n*sqrt(n)),求解規模較小的輸入,尚且沒有問題。但對於規模較大的n,演算法就力不從心了。有一種演算法叫厄拉多塞篩(sieve of eratosthenes),它在求解時具有相當高的效率,但是要犧牲較多的空間。

*//*

二.厄拉多塞篩演算法

這個程式的目標是,若i為素數,則設定a[i] = 1;如果不是素數,則設定為0。首先,將所有的陣列元素設為1,表示沒有已知的非素數。然後將已知為非素數(即為已知素數的倍數)的索引對應的陣列元素設定為0。如果將所有較小素數的倍數都設定為0之後,a[i]仍然保持為1,則可判斷它是所找的素數。

*/public

static

void

find2()

for (i = 2; i < n; i++)

if (convert.toboolean(a[i]))

//if (a[i] == 1)

\t", i);

}system.console.write("count: \n", count);

}/*例如,計算30以內的素數,先將所有陣列項初始化為1(如下第二列),表示還每發現非素數的數。接下來,將索引為2、3、5倍數的陣列項設定成0,因為2、3、5倍數的數是非素數。保持為1的陣列項對應索引為素數(如下最右列)。

i 2 3 5 a[i]

2 1 1

3 1 1

4 1 0

5 1 1

6 1 0

7 1 1

8 1 0

9 1 0

10 1 0

11 1 1

12 1 0

13 1 1

14 1 0

15 1 0

16 1 0

17 1 1

18 1 0

19 1 1

20 1 0

21 1 0

22 1 0

23 1 1

24 1 0

25 1 0

26 1 0

27 1 0

28 1 0

29 1 1

30 1 0

如何理解厄拉多塞篩演算法呢?

我們一定記得小學時候就學過的素數和合數的性質:任何乙個合數一定可以表示成若干個素數之積。如:4 = 2 * 2,6 = 2 * 3,12 = 2 * 2 * 3。也就是說,合數n一定是小於n的某個(或若干)素數的整數倍,反之,如果n不是任何比它小的素數的倍數,則n必然是素數。

*//*

三.經典演算法的改進版本

經典素數判定演算法中,並不需要用2到sqart(n)之間的所有整數去除n,只需要用其間的素數就夠了,原因也是合數一定可以表示成若干個素數之積。演算法的改進版本如下:

*/public

static

void

find3()

if (convert.toboolean(flag))

//if (flag == 1)

\t", n);}}

system.console.write("count: \n", count);

}/*演算法雖然在效率下,比先前版本有所提高,但需要犧牲空間記住已確定的素數。

*//*

四.厄拉多塞篩演算法的改進版

程式1-2使用乙個陣列來包含最簡單的元素型別,0和1兩個值,如果我們使用位的陣列,而不是使用整數的陣列,則可獲得更高的空間有效性。

*///const n 1000000;

//static int bitsperword = 2;

//const int shift = 1;

//const int mask = 0x1;

//static int bitsperword = 4;

//const int shift = 2;

//const int mask = 0x3;

//static int bitsperword = 8;

//const int shift = 3;

//const int mask = 0x7;

//static int bitsperword = 16;

//const int shift = 4;

//const int mask = 0xf;

static

int bitsperword = 32;

const

int shift = 5;

const

int mask = 0x1f;

//static int bitsperword = 64;

//const int shift = 6;

//const int mask = 0x3f;

//static int bitsperword = 128;

//const int shift = 7;

//const int mask = 0x7f;

//static int bitsperword = 256;

//const int shift = 8;

//const int mask = 0xff;

static

int count = 1+n/bitsperword; //bit i 對映數i

public

static

void

find4()

"[" + test(a, i) + "]");}}

for (i = 2; i < n; i++)

", i);}}

system.console.write("count: of \n", count,n);

}static

void

set(int a, int i)

static

void clr(int a, int i)

static

int test(int a, int i)

static

int set2(int a, int i)

static

int clr2(int a, int i)

}}

厄拉多塞篩法

簡介 1 厄拉多塞篩法 簡介 西元前250年,希臘數學家厄拉多塞 eeatosthese 想到了乙個非常美妙的質數篩法,減少了逐一檢查每個數的的步驟,可以比較簡單的從一大堆數字之中,篩選出質數來,這方法被稱作厄拉多塞篩法 sieve of eeatosthese 具體操作 先將 2 n 的各個數放入...

厄拉多塞篩法

厄拉多塞篩演算法 eratosthenes sieve 是一種求素數的方法,由古希臘數學家厄拉多塞提出。它的原理是,給定乙個數 n,從 2 開始依次將 sqrt 以內的素數的倍數標記為合數,標記完成後,剩餘未被標記的數為素數 從 2 開始 如此可省去檢查每個數的步驟,使篩選素數的過程更加簡單。厄拉多...

LeetCode 計數質數(厄拉多塞篩法)

2020年5月27日 解題 質數寫法的固化思維使人第一想法就寫出下面的 厄拉多塞篩法通過質數推算出接下來的非質數,一直算到n。舉個例子 質數2,我們可以推算出2x2 4 2x3 6 2x4 8等,能發現質數的倍數都是非質數,標記下來 接下來到質數3,我們可以推算出3x2 6 3x3 9 3x4 12...