Первые 1000 простых чисел с SQL Server - PullRequest
0 голосов
/ 19 сентября 2019

Я получил программу для Prime, которая дает только 2 в качестве вывода.Это должно дать мне все на основе Java-программы, которую я написал.

Вот SQL, который я создал для простых чисел.Это в SQL Server.Я хочу напечатать первые 1000 простых чисел.Не могли бы вы сообщить мне проблему в этом коде?

    DECLARE @i INT = 1
    DECLARE @j INT = 2
    DECLARE @COUNT INT
    BEGIN
    WHILE @j <= 10
        BEGIN
            SET @COUNT = 0
            WHILE @i <= @j
                BEGIN
                    BEGIN
                        IF((@j % @i) = 0)
                            SET @COUNT += 1
                    END
                    SET @i += 1
                END
            BEGIN
                IF (@COUNT = 2)
                    PRINT @j
            END
            SET @j += 1
        END
    END
    ;

Спасибо !!!

Ответы [ 3 ]

3 голосов
/ 19 сентября 2019

Ради забавы (и я чувствую, что я, вероятно, ответил на чье-то домашнее задание, но эй ...), как уже говорилось, Tally будет намного быстрее:

WITH N AS (
    SELECT N
    FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N(N)),
Tally AS(
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS I
    FROM N N1, N N2, N N3), --1,000 Numbers
Remainders AS(
    SELECT T1.I AS [Integer],
           T2.I AS Divider,
           T1.I % T2.I AS Remainder
    FROM Tally T1
         JOIN Tally T2 ON T1.I >= T2.I)
SELECT R.[Integer] AS PrimeNumber
FROM Remainders R
GROUP BY R.[Integer]
HAVING COUNT(CASE WHEN R.Remainder = 0 THEN 1 END) <= 2
ORDER BY R.[Integer];

Это довольно быстро, когдавы делаете это для 1000 строк, но (что неудивительно) время выполнения начинает экспоненциально увеличиваться при увеличении диапазона.

1 голос
/ 19 сентября 2019

У меня было решение, похожее на решение Ларну, но я пошел на собрание и не хотел, чтобы оно пропало даром.Он генерирует 1229 простых чисел (все простые числа меньше 10 000) за 7 секунд.

WITH 
E(n) AS(
    SELECT n FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0))E(n)
),
E2(n) AS(
    SELECT a.n FROM E a, E b
),
E4(n) AS(
    SELECT a.n FROM E2 a, E2 b
),
cteTally(n) AS(
    SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) n
    FROM E4
)
SELECT n
FROM cteTally t
WHERE (SELECT COUNT(*)
                FROM cteTally i
                WHERE t.n % i.n = 0
                AND i.n < t.n) = 1;

Он может работать намного быстрее, если нам разрешено использовать некоторые жестко закодированные значения.

WITH 
E(n) AS(
    SELECT n FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0))E(n)
),
E2(n) AS(
    SELECT a.n FROM E a, E b
),
E4(n) AS(
    SELECT a.n FROM E2 a, E2 b
),
cteTally(n) AS(
    SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) n
    FROM E4
)
SELECT *
FROM (VALUES(2),(3),(5),(7))x(n)
UNION ALL
SELECT n
FROM cteTally t
WHERE t.n % 2 <> 0
AND t.n % 3 <> 0 
AND t.n % 5 <> 0 
AND t.n % 7 <> 0 
AND (SELECT COUNT(*)
                FROM cteTally i
                WHERE t.n % i.n = 0
                AND i.n < t.n) = 1;

РЕДАКТИРОВАТЬ: последняя версия занимает 1 секунду, чтобы найти все простые числа ниже 10K, но идет до 2,5 минут, чтобы получить все простые числа ниже 100K (9592 простых чисел).

РЕДАКТИРОВАТЬ 2: Вот вариант, который объединяет обе версии для повышения производительности на больших наборах данных.Ему также не понадобится большой подсчетный стол.

DECLARE @j INT = 1;

CREATE TABLE #Primes( N int);
BEGIN TRY
    BEGIN TRANSACTION;

    WHILE @j <= 1000000
    BEGIN
        INSERT INTO #Primes
        SELECT @J
        FROM #Primes
        WHERE @j % n = 0
        HAVING COUNT(*) <= 1;

        SET @j += 1;
    END;

    COMMIT TRANSACTION;

    SELECT * 
    FROM #Primes
    WHERE N <> 1;
END TRY
BEGIN CATCH
    ROLLBACK TRANSACTION;
    THROW;
END CATCH;

DROP TABLE #Primes;
GO 
1 голос
/ 19 сентября 2019

Чтобы ответить на вопрос, который вы задали:

Не могли бы вы сообщить мне проблему в этом коде?

Проблема с вашим кодом состоит в том, что вы никогда не сбрасываете@i возвращается к 1, когда вы переходите к следующему значению @j.

        ...
        END
        SET @i = 1   --add this line to fix it
        SET @j += 1
        ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...