1
DECLARE @c int = 1000;
DECLARE @numbers TABLE (n int NOT NULL PRIMARY KEY);
DECLARE @products TABLE (p int NOT NULL PRIMARY KEY);
DECLARE @primes TABLE (p int NOT NULL PRIMARY KEY);
-- The 'composite exclusion' approach
-- 1. list all n = 2, 3, 4, ... c
WITH numbers AS
(
SELECT 2 AS n
UNION ALL
SELECT n + 1 FROM numbers
WHERE n <= @c - 1
)
INSERT INTO @numbers SELECT n FROM numbers OPTION(MAXRECURSION 0);
-- 2. find all products n x n <= c
WITH products AS
(
SELECT DISTINCT m.n * n.n AS p
FROM @numbers m LEFT OUTER JOIN
@numbers n ON 1 = 1
WHERE m.n * n.n <= @c
)
INSERT INTO @products SELECT p FROM products;
-- 3. numbers with no matching products are not composite, i.e, they're prime numbers.
INSERT INTO @primes
SELECT n.n FROM @numbers n LEFT JOIN @products p ON n.n = p.p WHERE p.p IS NULL;
這是一種通過Eratosthenes方法的Sieve。這是一個列舉素數的好算法嗎?
我見過循環,存儲過程等等,以及僞代碼和其他語言實現,但在我看來,這種簡單的基於集合的方法源於定義的素數應該就足夠了。
請記住,我不關心性能或內存消耗或優化在這個時候,我沒有測試它與更大的數字。我只想發佈算法,並讓人們確認(或挑戰)從列表中排除複合數字就足夠了。
(1)這不是適合算法的評論網站,所以你的問題還不清楚。 (2)爲什麼要在數據庫中生成素數? (3)如果你要在數據庫中完成Eratosthenes的Sieve,可以生成你想要的所有數字,把它們放在一個表中,然後使用'delete'去除複合數字。 –
感謝您的意見。我想正確的問題是如果有一個更好的算法 - 並且有,理貨表。這只是一個練習;我想我正在尋找一個「僅插入」,易於閱讀的方法;理貨方法的可讀性較差,但比我的便宜得多。 – thor2k