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