Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.56/68: Рейтинг темы: голосов - 68, средняя оценка - 4.56
10 / 10 / 1
Регистрация: 27.06.2013
Сообщений: 151

Алгоритм нахождения простых чисел

21.07.2013, 16:52. Показов 14177. Ответов 38
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Вопросы:
1) Нужен алгоритм проверки числа (является ли число простим). Нужно чтобы алгоритм был быстрым (нужно проделать 104 операций за 0.5 сек )!!!!
2) Почему мой алгоритм проверки не всегда дает верный ответ?

C++
1
if(x%2 && x%3 && x%5 && x%7) std::cout << "Число простое!\n";
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
21.07.2013, 16:52
Ответы с готовыми решениями:

Алгоритм нахождения простых чисел
Не могу найти в интернете нормальный код алгоритма нахождения простых чисел. Помогите пожалуйста. Добавлено через 2 минуты ...

Алгоритм нахождения простых чисел
Не так давно начал изучать с++. Вот попытался написать программу которая вычисляет простое ли число которые вы ввели в консоль? но она...

Алгоритм нахождения ПРОСТЫХ чисел в файле
Заполнить файл f целыми числами, полученными с помощью генератора случайных чисел. Из файла f получить файл g, оставив только ПРОСТЫЕ...

38
194 / 174 / 30
Регистрация: 10.07.2012
Сообщений: 800
21.07.2013, 17:01
Цитата Сообщение от ALEXKIRNAS Посмотреть сообщение
Нужно чтобы алгоритм был быстрым (нужно проделать 109 операций за 0.5 сек )
че за хрень вы несете?
2) предположу, что у некоторых чисел могут быть другие делители, кроме этих 4. что касается вашего алгоритма, он назовет "простыми" как раз только составные числа.

Добавлено через 2 минуты
если речь шла о том, чтобы проверить 104 чисел, то при определенных ограничениях и обычный n*sqrt(n) зайдет.
1
10 / 10 / 1
Регистрация: 27.06.2013
Сообщений: 151
21.07.2013, 17:11  [ТС]
Цитата Сообщение от salam Посмотреть сообщение
обычный n*sqrt(n) зайдет
Можно кусок кода (алгоритм)!!!
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,532
Записей в блоге: 1
21.07.2013, 17:26
C++
1
2
3
4
5
6
7
8
9
10
int is_prime(int n){
  int i=3;
  if(!n&1) return 0;
  if (n==1 || n==2 || n==3) return 1;
  do{
    if(n%i) return 0;
    i+=2;
  }while(i*i<=n);
  return 1;
}
0
 Аватар для dr.curse
404 / 360 / 36
Регистрация: 11.10.2010
Сообщений: 1,907
21.07.2013, 17:29
Kuzia domovenok, и что по твоему код рабочий?
http://codepad.org/yFCxb3JO
0
21.07.2013, 17:35

Не по теме:

Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
n&1

n==1 || n==2 || n==3
А как же ручная оптимизация индукции "i*i<=n"? А то вдруг компилятор вставит умножение?!

0
194 / 174 / 30
Регистрация: 10.07.2012
Сообщений: 800
21.07.2013, 17:38
Цитата Сообщение от ALEXKIRNAS Посмотреть сообщение
Можно кусок кода (алгоритм)!!!
категорически от вас требуется, чтобы проверка каждого числа на простоту выполнялась за корень. это выглядит так:
C++
1
2
3
4
5
6
bool _isprime(int n) {
   for(int i=2; i*i <= n; ++i)
      if(n % i == 0)
         return false;
   return true;
}
далее вы можете применять любые эвристики. самая очевидная: проверять только нечетные делители. практически целесообразно отсекать пару частых делителей. короче говоря, можно прийти к такому:

C++
1
2
3
4
5
6
7
bool _isprime(int n) {
   if(n & 1 == 0) return false;
   for(int i=3; i*i <= n; i += 2)
      if(n % i == 0)
         return false;
   return true;
}
Добавлено через 2 минуты
асимптотически, алгоритмы совершенно одинаковы, но в среднем второй должен работать в два раза быстрее.
1
~ Эврика! ~
 Аватар для OhMyGodSoLong
1258 / 1007 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
21.07.2013, 17:38
Почему никто ещё не посоветовал сделать табличку первых 6000 простых чисел?..
0
194 / 174 / 30
Регистрация: 10.07.2012
Сообщений: 800
21.07.2013, 17:41
Цитата Сообщение от OhMyGodSoLong Посмотреть сообщение
А как же ручная оптимизация индукции "i*i<=n"?
как вы предлагаете это оптимизировать?

Добавлено через 1 минуту
Цитата Сообщение от OhMyGodSoLong Посмотреть сообщение
Почему никто ещё не посоветовал сделать табличку первых 6000 простых чисел?..
потому же, почему никто не посоветовал сделать прекалк на первый миллиард чисел.
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,532
Записей в блоге: 1
21.07.2013, 17:41
Цитата Сообщение от aram_gyumri Посмотреть сообщение
Kuzia domovenok, и что по твоему код рабочий?
http://codepad.org/yFCxb3JO
А? Что? э... Конечно!
http://codepad.org/pfuUgwLP
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
int is_prime(unsigned int n){
  int i=1;
  if(!(n&1)) return 0;
  if (n==1 || n==2 || n==3) return 1;
  do{
    i+=2;
    if(!(n%i)) return 0;
  }while(i*i<=n);
  return 1;
}
int main(){
  printf(is_prime(5)?"prime":"not prime");
  return 0;
}
0
~ Эврика! ~
 Аватар для OhMyGodSoLong
1258 / 1007 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
21.07.2013, 17:44
Цитата Сообщение от salam Посмотреть сообщение
как вы предлагаете это оптимизировать?
C++
1
2
3
4
5
6
7
8
9
10
11
12
for(int i = 3; i*i <= n; i += 2)
 
||
\/
 
for (int i = 3, i_sq = 9; i_sq <= n; i_sq += (i + 1) << 2, i += 2)
 
||
\/
 
int n_sqrt = sqrt(n);
for (int i = 3; i <= n_sqrt; i += 2)
НИКОГДА НЕ ДОВЕРЯЙ КОМПИЛЯТОРУ! ВСЁ НАДО ОПТИМИЗИРОВАТЬ РУКАМИ! SSE-ИНСТРУКЦИЙ ТОЖЕ НЕ СУЩЕСТВУЕТ!

Извините.

Цитата Сообщение от salam Посмотреть сообщение
потому же, почему никто не посоветовал сделать прекалк на первый миллиард чисел.
Миллиард это много. А вот первые 6000 вполне влезут в кеш.
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,532
Записей в блоге: 1
21.07.2013, 17:51
Цитата Сообщение от OhMyGodSoLong Посмотреть сообщение
for (int i = 3, i_sq = 9; i_sq <= n; i_sq += (i + 1) << 2, i += 2)
Об этом я, кстати задумывался, как об альтернативе i*i, но решил, что выигрыш скорости не будет существеннен.
Цитата Сообщение от OhMyGodSoLong Посмотреть сообщение
int n_sqrt = sqrt(n);
for (int i = 3; i <= n_sqrt; i += 2)
а как же оптимизация sqrt?

Добавлено через 39 секунд
Цитата Сообщение от OhMyGodSoLong Посмотреть сообщение
НИКОГДА НЕ ДОВЕРЯЙ КОМПИЛЯТОРУ! ВСЁ НАДО ОПТИМИЗИРОВАТЬ РУКАМИ! SSE-ИНСТРУКЦИЙ ТОЖЕ НЕ СУЩЕСТВУЕТ!
Я это как раз понимаю, потому и не доверяю. А что такое SSE?
0
~ Эврика! ~
 Аватар для OhMyGodSoLong
1258 / 1007 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
21.07.2013, 17:52
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
а как же оптимизация sqrt?
1. Она вызывается один раз.
2. Я уверен, что алгоритм Ньютона в стандартной библиотеке и так заоптимизирован донельзя.

Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
Я это как раз понимаю, потому и не доверяю. А что такое SSE?
Я вообще в шутку это сказал, если что.

SSE — это то, что позволяет выполнять по четыре деления за один раз, что затыкает за пояс все эти "& 1" и прочее.
0
21.07.2013, 17:55

Не по теме:

Цитата Сообщение от OhMyGodSoLong Посмотреть сообщение
Я вообще в шутку это сказал, если что.
Я шутку понял, но доверия то не прибавилось всерьёз!

0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
21.07.2013, 18:13
Нашел на StackOverflow и внес незначительные изменения. ( http://stackoverflow.com/quest... r-is-prime )
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <iostream>
#include <chrono>
 
using namespace std;
 
__int64 power( int a, int n, int mod )
{
    __int64 power = a, result = 1;
    while ( n ) {
        if ( n & 1 ) result = (result * power) % mod;
        power = (power * power) % mod;
        n >>= 1;
    }
    return result;
}
 
bool witness( int a, int n )
{
    int t,u,i;
    __int64 prev,curr;
 
    u = n >> 1;
    t = 1;
 
    while ( !(u & 1) ) {
        u >>= 1;
        ++t;
    }
 
    prev = power( a, u, n );
    for ( i = 1; i <= t; ++i ) {
        curr = (prev * prev) % n;
        if ( (curr == 1) && (prev != 1) && (prev != n - 1) ) return true;
        prev = curr;
    }
    if ( curr != 1 ) return true;
    return false;
}
 
inline bool IsPrime( int number )
{
    if ( ((!(number & 1)) && number != 2) || (number < 2) || (number % 3 == 0 && number != 3) ) return false;
 
    if ( number < 1373653 ) {
        for( int k = 1; 36 * k * k - 12 * k < number; ++k )
            if ( (number % (6 * k + 1) == 0) || (number % (6 * k - 1) == 0) )
                return false;
        return true;
    }
 
    if ( number < 9080191 ) {
        if ( witness( 31, number ) ) return false;
        if ( witness( 73, number ) ) return false;
        return true;
    }
 
    if ( witness(  2, number ) ) return false;
    if ( witness(  7, number ) ) return false;
    if ( witness( 61, number ) ) return false;
    return true;
}
 
int main()
{
    chrono::system_clock::time_point a = chrono::system_clock::now();
    for ( unsigned int i = 0; i < 1000000; i++ ) {
        if ( IsPrime( i ) ) {
            cout << i << endl;
        }
    }
    chrono::system_clock::time_point b = chrono::system_clock::now();
    cout << chrono::duration_cast< chrono::milliseconds >( b - a ).count() << " ms.\n";
    return 0;
}
Среди чисел от 0 до 1 000 000 находит простые ~ за 386 ms. Ноутбук с Core i3, MinGW 4.7.3 (32 бита), ключ оптимизации -O0 (т.е. отключена)

Добавлено через 7 минут
Без вывода ~ 132 ms. (уже на MinGW 4.8.1)
0
45 / 48 / 5
Регистрация: 24.06.2013
Сообщений: 677
21.07.2013, 18:37
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
 
void main()
{
    int x;
    while(1)
    {
        printf("Vvedite chislo: ");
        scanf("%d",&x);
        system("cls");
        if(x==1 || x==2 || x==3 || (x-1)%6==0 || (x+1)%6==0)printf("Chislko %d - Naturalnoye!\n",x);
        else printf("Chislko %d - Ne naturalnoye!\n",x);
    }
}
ИМХО, вариант наиболее быстрый и вытекает из свойства простых чисел:

Всякое простое число, большее 3, представимо в виде или , где — некоторое натуральное число.(с)Википедия

Добавлено через 53 секунды
конечно бесконечный цикл нужно убрать по-хорошему )

Добавлено через 2 минуты
Выпали формулы =/
http://ru.wikipedia.org/wiki/Простое_число, там в разделе "Некоторые свойства" русским по белому написано это свойство натуральных чисел.
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
21.07.2013, 18:38
Retyrn0, 155 - простое число?
0
45 / 48 / 5
Регистрация: 24.06.2013
Сообщений: 677
21.07.2013, 18:39
Всякое простое число, большее 3, представимо в виде 6k+1 или 6k-1, где k — некоторое натуральное число.(c)

Добавлено через 1 минуту
Цитата Сообщение от lazybiz Посмотреть сообщение
155 - простое число
Пардоньте, я знал, что википедии доверять нельзя
0
49 / 23 / 3
Регистрация: 16.11.2011
Сообщений: 329
Записей в блоге: 5
21.07.2013, 18:41
вот, кое что было - игрался с С++11
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
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
 
using namespace std;
using namespace std::placeholders;
 
std::vector<int>simple_numbers(1,2); // перевое простое число 2
bool check_for_simple_numbers (int i, int x)
 {  return (x%i);}
 
 void finding_simple_numbers(int x)
 { for (int i = 3; i <= x; i+=2) // чётные числа нет смысла проверять
     { auto f = bind(check_for_simple_numbers, _1, i);
       if ( std::all_of( simple_numbers.begin(), simple_numbers.end(), f) )
          simple_numbers.push_back(i);
    }
 }
int main()
{   int x;
    cout << "Type number, all simple numbers before you want to be detected  \n";
    cin >> x;
 
 finding_simple_numbers(x);
 
 for ( auto i: simple_numbers)
     { std::cout << i <<" "; }
    return 0;
}
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
21.07.2013, 18:41
Цитата Сообщение от Retyrn0 Посмотреть сообщение
Пардоньте, я знал, что википедии доверять нельзя
Неужели в Википедии так и говориться? Дай ссылку.
Точнее ссылку я нашел, а где там такое сказано - нет.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
21.07.2013, 18:41
Помогаю со студенческими работами здесь

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

Нахождения больших простых чисел
Нахождения больших простых чисел. Реализовать программу на C++. спасибо за помощь

Программа для нахождения простых чисел от 1 до 100
Здравствуйте, в задании требуется написать программу для нахождения простых чисел от 1 до 100. В условии сказано, что необходимо создать...

Написать программу нахождения первых 50 простых чисел
Написать программу нахождения первых 50 простых чисел...Помогите пожалустно если можно то с коментариями!!

Напишите программу нахождения всех трехзначных простых чисел
Найти все трехзначные простые числа


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru