Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.68/735: Рейтинг темы: голосов - 735, средняя оценка - 4.68
Эксперт С++
 Аватар для Thinker
4267 / 2241 / 203
Регистрация: 26.08.2011
Сообщений: 3,802
Записей в блоге: 5

Быстрая проверка натурального числа на простоту

29.09.2012, 21:35. Показов 147023. Ответов 121
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Часто возникает задача проверки натурального числа на простоту. При этом имеются вероятностные и детерминированные методы проверки. Здесь рассматриваются только детерминированные алгоритмы, дающие 100% ответ на вопрос о простоте.

Хорошо известно такое утверждение: если натуральное число n>1 не делится ни на одно простое число, не превосходящее https://www.cyberforum.ru/cgi-bin/latex.cgi?\sqrt{n}, то оно простое. В связи с этим получается самый простой способ проверки на простоту алгоритм

C++
1
2
3
4
5
6
7
8
9
10
11
int Prime(unsigned long a)
{
   unsigned long i;
   if (a == 2)
      return 1;
   if (a == 0 || a == 1 || a % 2 == 0)
      return 0;
   for(i = 3; i*i <= a && a % i; i += 2)
      ;
   return i*i > a;
}
В данном алгоритме из множества https://www.cyberforum.ru/cgi-bin/latex.cgi?\{2,3,...,\sqrt{n}\} отброшено 50% четных чисел, так как если число a не делится на 2, то нет смыла делить его на 4, 6 и т.д. Данный метод можно усовершенствовать и отбросить из множества https://www.cyberforum.ru/cgi-bin/latex.cgi?\{2,3,...,\sqrt{n}\} больше чисел. Для этого выбирается некоторое число m, равное произведению простых чисел без степеней и рассматриваются только те элементы множества https://www.cyberforum.ru/cgi-bin/latex.cgi?\{2,3,...,\sqrt{n}\}, которые взаимно просты с m. Например, если m = 6 = 2*3, то из этого множества отбрасывается 66% элементов (ненужных проверок). В этом случае алгоритм будет быстрее предыдущего при больших n

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int Prime(unsigned long a)
{
   unsigned long i, j, bound;
   if (a == 0 || a == 1)
      return 0;
   if (a == 2 || a == 3 || a == 5)
      return 1;
   if (a%2 == 0 || a%3 == 0 || a%5 == 0)
      return 0;
   bound = sqrt((double)a);
   i = 7; j = 11;
   while (j <= bound && a%i && a%j)
   {
       i += 6; j += 6;
   }
   if (j <= bound || i <= bound && a%i == 0)
      return 0;
   return 1;
}
Если m = 30 = 2*3*5, то такой алгоритм будет еще быстрее и отбрасывает уже 74% лишних элементов

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
int Prime(unsigned long a)
{
   unsigned long i1, i2, i3, i4, i5, i6, i7, i8, bound;
   if (a == 0 || a == 1)
      return 0;
   if (a == 2 || a == 3 || a == 5 || a == 7 || a == 11 || a == 13 || a == 17 || a == 19 || a == 23 || a == 29)
      return 1;
   if (a%2 == 0 || a%3 == 0 || a%5 == 0 || a%7 == 0 || a%11 == 0 || a%13 == 0 || a%17 == 0 || a%19 == 0 || a%23 == 0 || a%29 == 0)
      return 0;
   bound = sqrt((double)a);
   i1 = 31; i2 = 37; i3 = 41; i4 = 43; i5 = 47; i6 = 49; i7 = 53; i8 = 59;
   while (i8 <= bound && a%i1 && a%i2 && a%i3 && a%i4 && a%i5 && a%i6 && a%i7 && a%i8)
   {
       i1 += 30; i2 += 30; i3 += 30; i4 += 30; i5 += 30; i6 += 30; i7 += 30; i8 += 30;
   }
   if (i8 <= bound ||
      i1 <= bound && a % i1 == 0 ||
      i2 <= bound && a % i2 == 0 ||
      i3 <= bound && a % i3 == 0 ||
      i4 <= bound && a % i4 == 0 ||
      i5 <= bound && a % i5 == 0 ||
      i6 <= bound && a % i6 == 0 ||
      i7 <= bound && a % i7 == 0)
         return 0;
   return 1;
}
Вот такие интересные наработки получились. У кого есть варианты, работающие быстрее, добавляйте.
33
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
29.09.2012, 21:35
Ответы с готовыми решениями:

Проверка на простоту числа
как мне сделать так, чтобы узнать простое является число или составное, не через bool, а как-нибудь через оператор switch case: т е, case...

Проверка числа на простоту
Помогите написать программу которая проверяет простое число или нет.

Проверка числа на простоту
Дано натуральное число n&gt;1. Проверьте, является ли оно простым. Программа должна вывести слово YES, если число простое и NO, если число...

121
0 / 0 / 0
Регистрация: 08.09.2014
Сообщений: 88
29.10.2015, 11:37
Студворк — интернет-сервис помощи студентам
C++
1
2
3
4
5
6
7
8
9
10
11
12
//------------Простое ли число?----------------------
bool isPrime(int number)
{
char buffer [50]="";
sprintf (buffer, "%d", number);
if (buffer [0] == '-')
return false;
if ( number == 0 || number == 1) return false;
int divisor;
for (divisor = number / 2; number%divisor != 0; --divisor);
return divisor == 1;
}
0
88 / 84 / 31
Регистрация: 18.11.2013
Сообщений: 390
30.10.2015, 13:41
Интересно, слышал ли кто-нибудь про тест чисел на простоту за log(N)? BPSW называется
недоказанный, но проверенный на всех числах до 1e15

Добавлено через 3 минуты
http://e-maxx.ru/algo/bpsw
0
0 / 0 / 0
Регистрация: 10.01.2017
Сообщений: 12
17.01.2017, 04:53
Как всегда сложно. Вот способ полегче
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
int main()
{
    const int N=50001;//Задаем размер выборки
    int arr[N];//Инициализируем массив для чисел 2 до N
    int k=0;
    int i;
    int bigResArr[N];//Результирующий массив для чисел больше 10
    int smallResArr[6];//Резальтирующий массив для чисел меньше 10
 
    //Цикл заполнения массива числами от 2 до N
    for(i=2; i<N; ++i){
        arr[k]=i;
        k++;
    }
 
    //Цикл для выполнения поиска и записавания простых чисел. Все операции привязаны к переменной k(номер элемента массивов)
    for(k=0; k<N; ++k)
    {
        if(arr[k]!=1 || arr[k]!=4 || arr[k]!=6 || arr[k]!=8 || arr[k]!=9)
        {
            //Условие заполнения результирующего массива простыми числами меньше 10
            if(arr[k]==2|| arr[k]==3 || arr[k]==5 || arr[k]==7)
            {
                smallResArr[k]=arr[k];
            }
            else
                {
            //Условие заполнения результирующего массива простыми числами большими чем 10
            if(arr[k]%2==0 || arr[k]%3==0 || arr[k]%5==0 || arr[k]%7==0)
                    {
                
                    }
            else
                        {
            bigResArr[k]= arr[k];
                        }       
                }
        }
    }
return 0;
}
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,876
17.01.2017, 05:14
Цитата Сообщение от TFR104 Посмотреть сообщение
//Условие заполнения результирующего массива простыми числами большими чем 10
if(arr[k]%2==0 || arr[k]%3==0 || arr[k]%5==0 || arr[k]%7==0)
число 121 простое?
не делится ни на 2, ни на 3, ни на 5, ни на 7
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13225 / 6857 / 1827
Регистрация: 18.10.2014
Сообщений: 17,379
17.01.2017, 05:16
Цитата Сообщение от TFR104 Посмотреть сообщение
Вот способ полегче
И что это вообще за чудо креативного программирования? Что, по-вашему, делает этот код? Числа 121, 143, 187 и т.д. смело отправляются в bigResArr, что, как мой умище мне подсказывает, означает, что они простые, так?
0
Неэпический
 Аватар для Croessmah
18150 / 10732 / 2067
Регистрация: 27.09.2012
Сообщений: 27,047
Записей в блоге: 1
17.01.2017, 05:49
Цитата Сообщение от TFR104 Посмотреть сообщение
Вот способ полегче
Вот еще легче:
C++
1
2
3
4
5
6
7
8
#include <iostream>
 
int main()
{
   int x = 10;
   std::cin >> x;
   std::cout << ((x&1)?"prostoe, sto pudov":"ne prostoe") << std::endl;
}
0
0 / 0 / 0
Регистрация: 10.01.2017
Сообщений: 12
17.01.2017, 05:51
Действительно. Ну так вы же модератор. Удалите сообщения.
0
0 / 0 / 0
Регистрация: 06.04.2017
Сообщений: 2
06.04.2017, 22:25
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//программа поиска простых чисел методом перебора делителей
#include<iostream>
#include <ctime>
using namespace std;
 
 
int main() 
{
    long max =1000000;//диапазон поиска от 1 до мах
    int n(0);//счетчик найденных простых чисел
    int s;
    clock_t timer;
    timer = clock();//время начала поиска
    cout << "Simple numbers: 0>>>"<<max<<endl;
    
    for ( int i = 1; i < max; i+=2)//проверяем все нечетные числа
    {
        s=0;//обнуляем счетчик делителей
        for (int j = 3; j <= i/j; j++) {
            //находим остаток от деления числа i на j 
            if (i % j == 0) {
                s++;//если остаток от деления равно 0, то j является делителем числа i, увеличиваем счетчик делителей на 1
                break;//проверяем следующее число
            }
        }
        if (s == 0) {  n++; }//простое число равно значению i при желании можно распечатать на экран, но снижает скорость
        
    }
    timer = clock()-timer ;//вычисляем время потраченное на поиск
    cout << "\n\aend:" << float(timer)/CLOCKS_PER_SEC<<"s"<<endl;
    cout << "find " << n << " numbers.\n";
    system("pause");
    return 0;
}
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,876
06.04.2017, 22:48
Цитата Сообщение от PetrSergeev Посмотреть сообщение
long max =1000000;//диапазон поиска от 1 до мах
маловато чтото за миллион тут бы т разговора не было
Цитата Сообщение от PetrSergeev Посмотреть сообщение
//проверяем все нечетные числа
а четные куда дел? число 2 простое
0
0 / 0 / 0
Регистрация: 06.04.2017
Сообщений: 2
07.04.2017, 09:33
Цитата Сообщение от ValeryS Посмотреть сообщение
маловато чтото за миллион тут бы т разговора не было
а четные куда дел? число 2 простое
2 - простое, но оно известно, просто распечатать надо в самом начале. Дальше вроде все правильно находит.... можно приспособить для проверки одного числа или поиска в диапазоне от min до max. 10млн у меня перебирает за 20 с, 1 млн меньше 1с.
0
Диссидент
Эксперт C
 Аватар для Байт
27714 / 17332 / 3810
Регистрация: 24.12.2010
Сообщений: 38,978
08.04.2017, 23:48
ValeryS, Имхо, этот форум для того и создан, чтобы люди совершенно разной квалификации предлагали решения как простых, так и сложных задач. И понимали бы суть задачи так, как она им видится. И предлагали бы временами свои, вполне симпатичные, решения

Добавлено через 2 минуты
Цитата Сообщение от PetrSergeev Посмотреть сообщение
10млн у меня перебирает за 20 с, 1 млн меньше 1с.
Это очень плохой результат даже для маломощных компьютеров типа 1 ГигаФлоп. Твой алгоритм делает чудовищное количество лишних проверок.
0
0 / 0 / 1
Регистрация: 22.04.2017
Сообщений: 105
12.05.2018, 13:03
Предлагаю самый неэффективный способ(Сам способ придумал не я, просто предлагаю) проверить число на простоту (Зато оригинальный):

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
int k;
    vector<int> Array;               //Создаем переменную для числа и Вектор с последовательностью Люка
    
    
    while(true)                      //Бесконечный цикл
    {
    
    system("cls");
    cout << "Enter your number: ";
    cin >> k;
    Array.reserve(k);
    Array[0] = 2;
    Array[1] = 1;                              //Запрос данных, а так же подготовка Вектора
    
    for(int i = 0; i < k - 1; i++)                          //Генерим последовательность до нужного числа
    {
        Array[i + 2] = Array[i + 1] + Array[i];
    }
    
    
    if((Array[k] - 1) % k == 0)                                                //Проверка по формуле
    {
        cout <<"\n\n"<< k <<" is Simple  (1)...\n";
        //cout << "\n\n\nOSU: " << (Array[k] - 1) % k << "\n\n";
       //cout << "\n\n\n(" << Array[k - 1] << " - 1) / " << k << "\n\n";          В комменте отладочная информация
        cout << "\n\n\n\n\nInput Any Key and Press Enter\n\n"; 
        cin >> k;
    }
    
    
    
    else
    {
        cout <<"\n\n"<< k <<" is not Simple (0)...\n"; 
      //    cout << "\n\n\n(" << Array[k - 1] << " - 1) / " << k << "\n\n";
        cout << "\n\n\n\n\nInput Any Key and Press Enter\n\n";
        cin >> k;
    }
    
    
    }
Формула:

L - Последовательность Люка

Если остаток (L[N] - 1) / N Равен 0, то число простое
0
 Аватар для bedvit
1210 / 261 / 22
Регистрация: 20.05.2016
Сообщений: 1,147
Записей в блоге: 22
12.05.2018, 20:51
Если интересно, когда то писал Быстрый алгоритмы поиска простых/всех делителей натурального числа (в т.ч. факторизация натурального числа)С++ Довольно шустрый, используется wheel factorization и многопоточность вычисления. Thinker, можно сверить результаты с вашим решением.
0
0 / 0 / 1
Регистрация: 22.04.2017
Сообщений: 105
12.05.2018, 23:46
К сожалению, основаная неээфективность представленного мной способа в том, что он способен вычислять числа не более чем 45. Далее последовательность Люка выходит за границы (число можно расширить если взять int 64), в любом случае некая ограниченность есть. (Справедливости ради скажу, что в этих пределах все известные мне алгоритмы уступают по производительности этому, надо будет еще сверить с вашим)

Я еще не вчитывался особо в ваш, но выглядит довольно интересно, правда, я для полной красоты сделал бы перебор рекурсивным.
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,876
13.05.2018, 07:34
вот еще интересное решение
C++
1
2
3
4
5
6
for (j=2; j<=(i/j); j++)
if (!(i%j)) break;
if (j > (i/j)) cout << i << " - simple number\n";
}
return 0;
}
взято отсюда Объяснить работу кода
0
2688 / 2260 / 244
Регистрация: 03.07.2012
Сообщений: 8,231
Записей в блоге: 1
13.05.2018, 08:53
Проверка j<=i/j математически эквивалентна j*j<=i, но работает медленнее.
Кроме того, идет проверка четных j, так что алгоритм совсем тормозной.
А алгоритм с j*j<=i и проверкой только четных уже был...
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,876
13.05.2018, 09:07
Цитата Сообщение от zer0mail Посмотреть сообщение
Проверка j<=i/j математически эквивалентна j*j<=i, но работает медленнее.
откуда такая уверенность?
j*j при больших числах возможно переполнение, при делении такой угрозы нет
0
2688 / 2260 / 244
Регистрация: 03.07.2012
Сообщений: 8,231
Записей в блоге: 1
13.05.2018, 09:19
Цитата Сообщение от ValeryS Посмотреть сообщение
j*j при больших числах возможно переполнение, при делении такой угрозы нет
Поэтому я и написал "математически". Кроме того, в теме было сообщение, где граница вычисляется 1 раз, до цикла.
А уж про проверку четных и говорить на стоит, настолько это неэффективно...
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,876
13.05.2018, 09:27
Цитата Сообщение от zer0mail Посмотреть сообщение
А уж про проверку четных и говорить на стоит, настолько это неэффективно...
ну про это я и не спорю
Цитата Сообщение от zer0mail Посмотреть сообщение
где граница вычисляется 1 раз, до цикла.
и про это тоже
мне понравилось нахождение предела равное корню
0
2688 / 2260 / 244
Регистрация: 03.07.2012
Сообщений: 8,231
Записей в блоге: 1
13.05.2018, 12:58
Цитата Сообщение от ValeryS Посмотреть сообщение
мне понравилось нахождение предела равное корню
Ну, это ведь тоже "математически"...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
13.05.2018, 12:58

Проверка числа на простоту
Хочу проверить число на простоту, но не вижу ошибку в коде. Можете подсказать, что не так? #include &lt;iostream&gt; #include...

Проверка числа на простоту
Написать программу, которая запрашивает массив натуральных чисел (ввод с клавиатуры), а затем выводит на экран те элементы массива, которые...

Проверка числа на простоту
Помогите решить 2 задачки, пожалуйста, 1. Написать программу для проверки натурального числа N на простоту. N вводится с клавиатуры. ...

Проверка числа на простоту
я реализовал вот так, но алгоритм очень долгий, мне надо проверять очень большое количество чисел (десятки тысяч) и он так надолго виснет...

Проверка числа на простоту
Дано натуральное число N, проверить, простое оно или нет. Увеличить его значение на натуральное число M. Проверить, осталось ли оно ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
100
Ответ Создать тему
Новые блоги и статьи
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 31.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru