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...