Какой алгоритм поиска простых чисел самый быстрый?

Какой алгоритм поиска простых чисел с помощью C++ является самым быстрым? Я использовал алгоритм сита, но все же хочу, чтобы он работал быстрее!

Я нашел старую статью, но выглядит интересно: Веселье с простыми числами

Mvcoile 30.06.2012 16:37

@Jaider это не работает для чисел всего 7 (111). Это также не работает для 1001 = 9. И, очевидно, он не работает почти для всех простых чисел в целом (не распространяется на случай 2 ^ p - 1, которые являются простыми числами Мерсенна - классически сгенерированными примерами - которые всегда будут иметь форму 111 ... 1)

Daniel Kats 21.11.2012 21:07

@Kasperasky - Вы не упомянули, какое сито? Вы, наверное, имеете в виду Сито Эрантоза!

user2618142 06.11.2017 12:35

Алгоритм Сито Эратосфена

Emad Aghayi 04.05.2020 06:46
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
197
4
335 993
17

Ответы 17

Очень быстрая реализация Сито Аткина - это Primegen Дэна Бернштейна. Это сито более эффективно, чем Сито Эратосфена. На его странице есть контрольная информация.

На самом деле я не думаю, что Primegen самый быстрый или даже второй по скорости; Я думаю, что yafu и primesieve в целом быстрее, и, конечно, более 2 ^ 32. Оба являются (модифицированными) ситами Эратосфена, а не ситом Аткина-Бернштейна.

Charles 19.08.2011 08:29
Primesieve Сито Эратосфена (SoE) - это самый быстрый из возможных алгоритмов, который всегда будет быстрее, чем любая реализация SoA Сита Аткина, включая алгоритм Бернштейна, как указано в этом ответе, потому что сито уменьшает количество операций по сравнению с SoA: для 32- диапазон битовых чисел (2 ^ 32-1), primesieve выполняет около 1,2 миллиарда отбраковок, тогда как SoA выполняет в общей сложности около 1,4 миллиарда комбинированных операций переключения и освобождения от квадратов, причем обе операции имеют примерно одинаковую сложность и могут быть оптимизированы примерно одинаково способ.
GordonBGood 06.12.2013 07:06

Продолжение: Бернштейн сравнил только SoE, используя ту же эффективную факторизацию колеса, что и для SoA, который представляет собой колесо 2; 3; 5, использование которого приводит к примерно 1,83 миллиардам отбраковок в 32-битном диапазоне чисел; это делает SoA примерно на 30% быстрее при сравнении этой ограниченной версии SoE для эквивалентных других оптимизаций. Однако алгоритм простого просева использует колесо 2; 3; 5; 7 в сочетании с предварительным отбраковкой сегмента колеса 2; 3; 5; 7; 11; 13; 17, чтобы сократить количество операций примерно до 1,2 миллиарда для выполнения примерно На 16,7% быстрее, чем SoA, с эквивалентной оптимизацией рабочего цикла.

GordonBGood 06.12.2013 07:16

Продолжение 2: У SoA нет факторизации колеса с более высоким коэффициентом, используемой, чтобы иметь большое значение, поскольку колесо факторизации 2; 3; 5 является "запекшейся" частью алгоритма.

GordonBGood 06.12.2013 07:18

@GordonBGood, если верить википедии, сито Аткина имеет (очень) немного лучшую вычислительную сложность на коэффициент log log N. Конечно, это настолько мало, что не будет иметь большого значения, чем обычная настройка.

Eamon Nerbonne 01.06.2014 15:29

@Eamon Nerbonne, WP правильный; однако простое улучшение вычислительной сложности не делает алгоритмы более быстрыми для общего использования. В этих комментариях я имею в виду, что максимальная колесная факторизация Сита Эратосфена (SoE) (что невозможно для Сита Аткина-SoA) приводит к немного меньшему количеству операций для SoE вплоть до диапазона примерно миллиарда. Намного выше этой точки обычно необходимо использовать сегментацию страниц для преодоления ограничений памяти, и именно здесь SoA дает сбой, требуя быстро увеличивающихся постоянных накладных расходов с увеличением диапазона.

GordonBGood 01.06.2014 18:37

В. Кто-нибудь знает, как использовать Сито Аткина, вызывая родной язык в Java? Другими словами, я хотел бы связать библиотеку, написанную на C, с Java, используя собственный код, а не переписывать ее на Java?

Beezer 06.12.2016 02:49

Если это должно быть очень быстро, вы можете включить список простых чисел:
http://www.bigprimes.net/archive/prime/

Если вам просто нужно знать, является ли определенное число простым числом, существуют различные основные тесты, перечисленные в Википедии. Вероятно, это самый быстрый способ определить, являются ли большие числа простыми числами, особенно потому, что они могут сказать вам, является ли число нет простым.

Список всех простых чисел? Я думаю, вы имеете в виду список первых нескольких простых чисел ... :)

j_random_hacker 18.01.2009 07:19

Если называть 100000000 несколько, то да. :)

Georg Schölly 18.01.2009 10:35

конечно 100000000 - это "несколько" по сравнению с бесконечностью;)

Timofey 21.01.2012 20:08

Как вы думаете, почему Сито Аткина (SoA) быстрее, чем Сито Эратосфена (SoE)? Это, конечно, не тогда, когда вы просто реализуете программу с использованием псевдокода, как в статье Википедии, которую вы связали. Если SoE реализуется с таким же уровнем возможных оптимизаций, как и в SoA, то для SoA требуется немного меньше операций для очень больших диапазонов просеивания, чем для SoE, но этот выигрыш обычно более чем компенсируется повышенной сложностью и дополнительные постоянные накладные расходы фактора этой вычислительной сложности, так что для практических приложений SoE лучше.

GordonBGood 20.03.2014 06:53

Простые числа хороши тем, что они не меняются. Если у вас есть список, вы можете использовать его вечно.

Mark Ransom 19.12.2020 07:06

Ваша проблема - решить, является ли конкретное число простым? Тогда вам понадобится тест на простоту (простой). Или вам нужны все простые числа до заданного числа? В этом случае подходят простые сита (легко, но требуют памяти). Или вам нужны простые множители числа? Это потребует факторизации (сложно для больших чисел, если вам действительно нужны наиболее эффективные методы). Насколько велики числа, на которые вы смотрите? 16 бит? 32 бита? больше?

Один из умных и эффективных способов - предварительно вычислить таблицы простых чисел и сохранить их в файле с помощью кодирования на битовом уровне. Файл считается одним длинным битовым вектором, тогда как бит n представляет собой целое число n. Если n простое, его бит устанавливается в единицу, в противном случае - в ноль. Поиск выполняется очень быстро (вы вычисляете байтовое смещение и битовую маску) и не требует загрузки файла в память.

Хороший тест на простоту конкурирует с задержкой в ​​основной памяти для простых таблиц, которые могут подходить для размещения, поэтому я бы не стал его использовать, если он не поместится в L2.

Charles 19.08.2011 08:37

Рабин-Миллер - стандартный вероятностный тест на простоту. (вы запускаете его K раз, и входное число либо определенно составное, либо, вероятно, простое с вероятностью ошибки 4-K. (несколько сотен итераций, и это почти наверняка говорит вам правду)

Есть маловероятный (детерминированный) вариант Рабина Миллера.

Отличный поиск в Интернете по Мерсенн Прайм (GIMPS), который установил мировой рекорд по наибольшему проверенному простому числу (274,207,281 - 1 по состоянию на июнь 2017 года), использует несколько алгоритмов, но это простые числа в особых формах. Однако приведенная выше страница GIMPS включает некоторые общие детерминированные тесты простоты. Похоже, они указывают на то, что какой алгоритм будет «самым быстрым», зависит от размера числа, которое нужно протестировать. Если ваше число умещается в 64 бита, вам, вероятно, не следует использовать метод, предназначенный для работы с простыми числами в несколько миллионов цифр.

Это зависит от вашего приложения. Есть некоторые соображения:

  • Вам нужна только информация о том, являются ли несколько чисел простыми, нужны ли вам все простые числа до определенного предела или вам нужны (потенциально) все простые числа?
  • Насколько велики цифры, с которыми вам приходится иметь дело?

Тесты Миллера-Рабина и аналогичные тесты только быстрее решета для чисел более определенного размера (где-то около нескольких миллионов, я полагаю). Ниже этого можно использовать пробное деление (если у вас всего несколько чисел) или сито.

Он, он, я знаю, что я некромант, отвечающий на старые вопросы, но я только что нашел этот вопрос, ища в сети способы реализации эффективных тестов простых чисел.

До сих пор я считаю, что самым быстрым алгоритмом проверки простых чисел является Strong Probable Prime (SPRP). Я цитирую форумы Nvidia CUDA:

One of the more practical niche problems in number theory has to do with identification of prime numbers. Given N, how can you efficiently determine if it is prime or not? This is not just a thoeretical problem, it may be a real one needed in code, perhaps when you need to dynamically find a prime hash table size within certain ranges. If N is something on the order of 2^30, do you really want to do 30000 division tests to search for any factors? Obviously not.

The common practical solution to this problem is a simple test called an Euler probable prime test, and a more powerful generalization called a Strong Probable Prime (SPRP). This is a test that for an integer N can probabilistically classify it as prime or not, and repeated tests can increase the correctness probability. The slow part of the test itself mostly involves computing a value similar to A^(N-1) modulo N. Anyone implementing RSA public-key encryption variants has used this algorithm. It's useful both for huge integers (like 512 bits) as well as normal 32 or 64 bit ints.

The test can be changed from a probabilistic rejection into a definitive proof of primality by precomputing certain test input parameters which are known to always succeed for ranges of N. Unfortunately the discovery of these "best known tests" is effectively a search of a huge (in fact infinite) domain. In 1980, a first list of useful tests was created by Carl Pomerance (famous for being the one to factor RSA-129 with his Quadratic Seive algorithm.) Later Jaeschke improved the results significantly in 1993. In 2004, Zhang and Tang improved the theory and limits of the search domain. Greathouse and Livingstone have released the most modern results until now on the web, at http://math.crg4.com/primes.html, the best results of a huge search domain.

См. Здесь для получения дополнительной информации: http://primes.utm.edu/prove/prove2_3.html и http://forums.nvidia.com/index.php?showtopic=70483

Если вам просто нужен способ генерировать очень большие простые числа и вы не хотите генерировать все простые числа <целое число n, вы можете использовать тест Лукаса-Лемера для проверки простых чисел Мерсенна. Простое число Мерсенна имеет вид 2 ^ p -1. Я думаю, что тест Лукаса-Лемера - это самый быстрый алгоритм, обнаруженный для простых чисел Мерсенна.

И если вы хотите использовать не только самый быстрый алгоритм, но и самое быстрое оборудование, попробуйте реализовать его с помощью Nvidia CUDA, напишите ядро ​​для CUDA и запустите его на GPU.

Вы даже можете заработать немного денег, если обнаружите достаточно большие простые числа, EFF разыгрывает призы от 50 до 250 тысяч долларов: https://www.eff.org/awards/coop

#include<stdio.h>
main()
{
    long long unsigned x,y,b,z,e,r,c;
    scanf("%llu",&x);
    if (x<2)return 0;
    scanf("%llu",&y);
    if (y<x)return 0;
    if (x==2)printf("|2");
    if (x%2==0)x+=1;
    if (y%2==0)y-=1;
    for(b=x;b<=y;b+=2)
    {
        z=b;e=0;
        for(c=2;c*c<=z;c++)
        {
            if (z%c==0)e++;
            if (e>0)z=3;
        }
        if (e==0)
        {
            printf("|%llu",z);
            r+=1;
        }
    }
    printf("|\n%llu outputs...\n",r);
    scanf("%llu",&r);
}    

r используется до инициализации

zumalifeguard 14.12.2011 07:44
#include <iostream>

using namespace std;

int set [1000000];

int main (){

    for (int i=0; i<1000000; i++){
        set [i] = 0;
    }
    int set_size= 1000;
    set [set_size];
    set [0] = 2;
    set [1] = 3;
    int Ps = 0;
    int last = 2;

    cout << 2 << " " << 3 << " ";

    for (int n=1; n<10000; n++){
        int t = 0;
        Ps = (n%2)+1+(3*n);
        for (int i=0; i==i; i++){
            if (set [i] == 0) break;
            if (Ps%set[i]==0){
                t=1;
                break;
            }
        }
        if (t==0){
            cout << Ps << " ";
            set [last] = Ps;
            last++;
        }
    }
    //cout << last << endl;


    cout << endl;

    system ("pause");
    return 0;
}

это должен быть ответ на тему «Как писать неструктурированный код, фактически не используя GOTO». Вся эта путаница просто для того, чтобы закодировать простое пробное деление! (n%2)+1+(3*n) хоть и хорош. :)

Will Ness 05.03.2012 01:25

@Will Ness Я бы не проголосовал за это как за ответ на этот вопрос; зачем использовать цикл for, когда подойдет макрос? :)

Rob Grant 11.02.2014 14:54
#include<iostream>
using namespace std;

void main()
{
    int num,i,j,prime;
    cout<<"Enter the upper limit :";
    cin>>num;

    cout<<"Prime numbers till "<<num<<" are :2, ";

    for(i=3;i<=num;i++)
    {
        prime=1;
        for(j=2;j<i;j++)
        {
            if (i%j==0)
            {
                prime=0;
                break;
            }
        }

        if (prime==1)
            cout<<i<<", ";

    }
}

это самое медленное, что вы можете сделать.

Will Ness 12.03.2012 22:16

Это очень медленно, если верхний предел, скажем, 10000000, этот код займет много времени !!

Dixit Singla 16.11.2013 15:36

этот код - O (N ^ 2 / log N). без break; это было бы еще медленнее, O (N ^ 2), но это уже можно было рассматривать как ошибку кодирования. сохранение и тестирование с помощью простых чисел - O (N ^ 2 / (log N) ^ 2), а тестирование только с помощью простых чисел, меньших квадратного корня числа, - O (N ^ 1.5 / (log N) ^ 2).

Will Ness 11.08.2014 13:27

@WillNess Возможно, немного преувеличивает. Он мог легко запустить цикл for с 1 вместо 2 и добавить j <= i вместо j <i. :)

Kenny Cason 04.10.2016 03:30

Я не думаю, что этот пост следует удалять, он служит ценным контрпримером.

Will Ness 04.10.2016 12:51

@KennyCason, это просто сломало бы код. но да, с тех пор я видел гораздо более медленные коды, например [n | n<-[2..], notElem(n) [j*k | j<-[2..(n-1)], k<-[2..(n-1)]]], или абсолютный победитель, let { isPrime(n) = n>1 && []==[i | i<-[2..n-1], isPrime(i) && rem(n)(i)==0] } in filter(isPrime) [2..] (в Haskell, извините; с использованием синтаксиса понимания списка; rem - для остатка, %; [] - пустой список). По сравнению с этими двумя, с одним здесь все в порядке (и, кстати, он эквивалентен предыдущему, если будет сделано одно важное - и простое - изменение).

Will Ness 04.10.2016 13:34

@WillNess, хорошо, ха-ха, я тоже кодирую на Haskell, поэтому могу это прочитать. :)

Kenny Cason 12.10.2016 23:25

Я знаю, что это несколько позже, но это может быть полезно людям, приходящим сюда с поисков. В любом случае, вот некоторый JavaScript, который полагается на тот факт, что нужно тестировать только простые множители, поэтому более ранние простые числа, сгенерированные кодом, повторно используются в качестве тестовых факторов для более поздних. Конечно, сначала отфильтровываются все значения четности и mod 5. Результат будет в массиве P, и этот код может обработать 10 миллионов простых чисел менее чем за 1,5 секунды на ПК i7 (или 100 миллионов примерно за 20). Переписать на C это должно быть очень быстро.

var P = [1, 2], j, k, l = 3

for (k = 3 ; k < 10000000 ; k += 2)
{
  loop: if (++l < 5)
  {
    for (j = 2 ; P[j] <= Math.sqrt(k) ; ++j)
      if (k % P[j] == 0) break loop

    P[P.length] = k
  }
  else l = 0
}

Это доставит вам много проблем, если вы создаете большое количество простых чисел, а для сравнений лучше использовать P [j] * P [j] <= k, потому что sqrt довольно медленный

Simon 26.06.2014 21:51

@Simon sqrt может быть выведен из цикла и вычислен только один раз, тогда как P[j]*P[j] должен вычисляться на каждой итерации. Я бы не стал думать, что один быстрее другого без тестирования.

Mark Ransom 19.12.2020 07:18

Существует 100% математический тест, который проверяет, является ли число P простым или составным, и называется Тест на первичность AKS.

Идея проста: для числа P, если все коэффициенты (x-1)^P - (x^P-1) делятся на P, то P - простое число, в противном случае - составное число.

Например, для P = 3 будет получен полином:

   (x-1)^3 - (x^3 - 1)
 = x^3 + 3x^2 - 3x - 1 - (x^3 - 1)
 = 3x^2 - 3x

И оба коэффициента делятся на 3, поэтому число простое.

И пример, когда P = 4, который НЕ является простым, даст:

   (x-1)^4 - (x^4-1)
 = x^4 - 4x^3 + 6x^2 - 4x + 1 - (x^4 - 1)
 = -4x^3 + 6x^2 - 4x

И здесь мы видим, что коэффициенты 6 не делятся на 4, следовательно, НЕ простое.

Полином (x-1)^P будет членами P+1 и может быть найден с помощью комбинации. Итак, этот тест будет запускаться в среде выполнения O(n), поэтому я не знаю, насколько это будет полезно, поскольку вы можете просто перебирать i от 0 до p и проверять оставшееся.

На практике AKS - очень медленный метод, не конкурирующий с другими известными методами. Описываемый вами метод - это не AKS, а вводная лемма, которая работает медленнее, чем неоптимизированное пробное деление (как вы указываете).

DanaJ 29.11.2014 09:41

привет @Kousha, что означает x? в (x-1)^P - (x^P-1). у вас есть образец кода для этого? в C++ для определения, является ли целое число простым или нет?

kiLLua 05.10.2016 10:59

@kiLLua X - это просто переменная. Это коэффициент при X, который определяет, является ли число простым или нет. И никакого кода у меня нет. Я не рекомендую использовать этот метод для определения простого числа. Это просто очень крутое математическое поведение простых чисел, но в остальном оно невероятно неэффективно.

Kousha 06.10.2016 21:24

Я всегда использую этот метод для вычисления простых чисел, следуя алгоритму сита.

void primelist()
 {
   for(int i = 4; i < pr; i += 2) mark[ i ] = false;
   for(int i = 3; i < pr; i += 2) mark[ i ] = true; mark[ 2 ] = true;
   for(int i = 3, sq = sqrt( pr ); i < sq; i += 2)
       if (mark[ i ])
          for(int j = i << 1; j < pr; j += i) mark[ j ] = false;
  prime[ 0 ] = 2; ind = 1;
  for(int i = 3; i < pr; i += 2)
    if (mark[ i ]) ind++; printf("%d\n", ind);
 }

Я позволю вам решить, самый быстрый он или нет.

using System;
namespace PrimeNumbers
{

public static class Program
{
    static int primesCount = 0;


    public static void Main()
    {
        DateTime startingTime = DateTime.Now;

        RangePrime(1,1000000);   

        DateTime endingTime = DateTime.Now;

        TimeSpan span = endingTime - startingTime;

        Console.WriteLine("span = {0}", span.TotalSeconds);

    }


    public static void RangePrime(int start, int end)
    {
        for (int i = start; i != end+1; i++)
        {
            bool isPrime = IsPrime(i);
            if (isPrime)
            {
                primesCount++;
                Console.WriteLine("number = {0}", i);
            }
        }
        Console.WriteLine("primes count = {0}",primesCount);
    }



    public static bool IsPrime(int ToCheck)
    {

        if (ToCheck == 2) return true;
        if (ToCheck < 2) return false;


        if (IsOdd(ToCheck))
        {
            for (int i = 3; i <= (ToCheck / 3); i += 2)
            {
                if (ToCheck % i == 0) return false;
            }
            return true;
        }
        else return false; // even numbers(excluding 2) are composite
    }

    public static bool IsOdd(int ToCheck)
    {
        return ((ToCheck % 2 != 0) ? true : false);
    }
}
}

Для поиска и печати простых чисел в диапазоне от 1 до 1000000 на моем ноутбуке Core 2 Duo с процессором 2,40 ГГц требуется примерно 82 секунды. И он нашел простые числа 78 498.

это слишком медленно. проблема в i <= (ToCheck / 3). это должен быть i <= (ToCheck / i). вместо этого он может работать за 0,1 секунды.

Will Ness 10.10.2018 18:11

Я написал его сегодня на C, скомпилировал с помощью tcc, разобрался во время подготовки к экзаменам несколько лет назад. не знаю, написал ли кто это уже сейчас. это действительно быстро (но вы должны решить, быстро это или нет). потребовалась одна или две минуты, чтобы найти около 100 004 простых числа от 10 до 1000000 на процессоре i7 при средней загрузке процессора 32%. как вы знаете, простыми могут быть только те, у которых последняя цифра либо 1,3,7, либо 9 и чтобы проверить, является ли это число простым или нет, вы должны разделить это число только на ранее найденные простые числа. поэтому сначала возьмите группу из четырех чисел = {1,3,7,9}, проверить это делением на известные простые числа, если напоминание не равно нулю, то число простое, добавьте его в массив простых чисел. затем добавьте 10 в группу, чтобы она стала {11,13,17,19}, и повторите процесс.

#include <stdio.h>
int main() {    
    int nums[4] = {1,3,7,9};
    int primes[100000];
    primes[0]=2;
    primes[1]=3;
    primes[2]=5;
    primes[3]=7;
    int found = 4;
    int got = 1;
    int m=0;
    int upto = 1000000;
    for(int i=0;i<upto;i++){
        //printf("iteration number: %d\n",i);
        for(int j=0;j<4;j++){
            m = nums[j]+10;
            //printf("m = %d\n",m);
            nums[j] = m;
            got = 1;
            for(int k=0;k<found;k++){
                //printf("testing with %d\n",primes[k]);
                if (m%primes[k]==0){
                    got = 0;
                    //printf("%d failed for %d\n",m,primes[k]);
                    break;
                }
            }
            if (got==1){
                //printf("got new prime: %d\n",m);
                primes[found]= m;
                found++;
            }
        }
    }
    printf("found total %d prime numbers between 1 and %d",found,upto*10);
    return 0;
}
#include <stdio.h>

int main() //works for first 10000 primes.
{
#define LEAST_PRIME 2

int remainder, number_to_be_checked = LEAST_PRIME, divisor = 2, remainder_dump, 
upper_limit; //upper limit to be specified by user.
int i = 1;
printf("            SPECIFY UPPER LIMIT:   ");
scanf("%d", &upper_limit);
printf("1. 2,\n", number_to_be_checked); //PRINTS 2.
do
{
    remainder_dump = 1;
    divisor = 2;

    do
    {
        remainder = number_to_be_checked % divisor;
        if (remainder == 0)
        {
            remainder_dump = remainder_dump * remainder; // dumping 0 for rejection.
        }
        ++divisor;

    } while (divisor <= number_to_be_checked/divisor); // upto here we know number is prime or 
not.
    if (remainder_dump != 0)
    {
        ++i;
        printf("%d.) %d.\t", i, number_to_be_checked); //print if prime.
    };
    number_to_be_checked = number_to_be_checked + 1;
} while (number_to_be_checked <= upper_limit);
printf("\nNUMBER OF PRIMES:           \t%d", i);

return 0;
}

Это может бесконечно перечислять простые числа. Извините за объем, я написал эту программу, когда я был всего 3 дня в программировании, поэтому она использует очень простые функции. После редактирования, предложенного в разделе комментариев, он печатает простое до 1000000 за 13 секунд.

DAMNNNNNN! ЭТО БЫЛО БЫСТРО. THNKSSSSSS ..............

Samarthya Singh 19.12.2020 07:36

Но, похоже, возникает проблема, когда я указываю верхний предел как 104729, он должен давать количество простых чисел как 10065 вместо правильного ответа 10000. Разве мы не должны также взять rt number_to_be_checked?

Samarthya Singh 19.12.2020 07:43

Это сработало!!! Но как?? Что касается того, насколько быстро это заняло 3 секунды на том же компьютере по сравнению с 13.

Samarthya Singh 19.12.2020 07:53

Если число n не является простым, оно будет иметь как минимум 1 делитель <= квадратный корень из n. Разница в скорости (повторение до n или его квадратного корня) еще более заметна с большим n.

chux - Reinstate Monica 19.12.2020 07:55

На вопросы и ответы можно «следить» с помощью кнопки «следовать».

chux - Reinstate Monica 19.12.2020 08:00

сначала я не понимал, что делает restder_dump, но теперь вижу: вы просто хотите записать, что число делится. Но в таком случае можно просто сломаться. Значительно ускорит процесс! Даже в этом случае это все еще простое итеративное решение, конечно, НЕ очень быстрое.

mous 09.02.2021 09:41

Вы можете попробовать этот код, самый быстрый способ получить простое число с меньшим количеством циклов, такое число, как 1000, получит менее 15 циклов

def divisors(integer):
    result = []
    i = 2
    j = integer/2
    while(i <= j):
        if integer % i == 0:
            result.append(i)
            if i != integer//i:
                result.append(integer//i)
        i += 1
        j = integer//i
    if len(result) > 0:
        return sorted(result)
    else:
        return f"{integer} is prime"


print(divisors(1827))
print(divisors(1025))
print(divisors(27))

Недавно я написал этот код, чтобы найти сумму чисел. Его можно легко изменить, чтобы определить, является ли число простым или нет. Тесты выполняются поверх кода.

// built on core-i2 e8400
// Benchmark from PowerShell
// Measure-Command { ExeName.exe }
// Days              : 0
// Hours             : 0
// Minutes           : 0
// Seconds           : 23
// Milliseconds      : 516
// Ticks             : 235162598
// TotalDays         : 0.00027217893287037
// TotalHours        : 0.00653229438888889
// TotalMinutes      : 0.391937663333333
// TotalSeconds      : 23.5162598
// TotalMilliseconds : 23516.2598
// built with latest MSVC
// cl /EHsc /std:c++latest main.cpp /O2 /fp:fast /Qpar

#include <cmath>
#include <iostream>
#include <vector>

inline auto prime = [](std::uint64_t I, std::vector<std::uint64_t> &cache) -> std::uint64_t {
    std::uint64_t root{static_cast<std::uint64_t>(std::sqrtl(I))};
    for (std::size_t i{}; cache[i] <= root; ++i)
        if (I % cache[i] == 0)
            return 0;

    cache.push_back(I);
    return I;
};

inline auto prime_sum = [](std::uint64_t S) -> std::uint64_t {
    std::uint64_t R{5};
    std::vector<std::uint64_t> cache;
    cache.reserve(S / 16);
    cache.push_back(3);

    for (std::uint64_t I{5}; I <= S; I += 8)
    {
        std::uint64_t U{I % 3};
        if (U != 0)
            R += prime(I, cache);
        if (U != 1)
            R += prime(I + 2, cache);
        if (U != 2)
            R += prime(I + 4, cache);
        R += prime(I + 6, cache);
    }
    return R;
};

int main()
{
    std::cout << prime_sum(63210123);
}

Другие вопросы по теме