C/C++

Решите задачу на языке С++. Алгоритм проверки числа на простоту (переборный)

#include <iostream>

using namespace std;

int main()
{
int num;
do
{
cout << "Введите натуральное число: ";
cin >> num;
} while(num < 1);
bool prostoje = true;
for(int x = 2; x < num; x++)
{
if(x != num)
{
if(num % x == 0)
{
prostoje = false;
break;
}
}
}
if(prostoje)
cout << "Простое число." << endl;
else
cout << "Не простое число." << endl;
return 0;
}
Арман Русланов
Арман Русланов
69 966
Лучший ответ
Андрей Глинский Думаю что нет смысла проверять делители размером более половины от числа. Ибо это даёт 2, а любые остальные будут меньше двух, т. е. дроби.
Для гигантских чисел с ситом Эратосфена можно так:
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cmath>
using namespace std;
unsigned long *a, b[32], c[32];
void fal(unsigned long x)
{ a[x >> 5] &= c[x & 31]; }
unsigned bit(unsigned long x)
{ return a[x >> 5] & b[x & 31]; }
int main()
{ unsigned long i, j, k, l, m, n = 4294967295, t;
unsigned long long N; i = 1; b[0] = i; c[0] = ~i;
t = time(NULL); for (j = 1; j < 32; j++) { i <<= 1;
b[j] = i; c[j] = ~i; } m = ceil((n + 1.) / 32);
a = new unsigned long [m]; for (i = 0; i <= m; i++)
a[i] = 4294967295; fal(0); fal(1); i = ceil(sqrt(n));
for (j = 2; j <= i; j++) if (bit(j)) { k = n / j; for (l = 2;
l <= k; l++) fal(l * j); } cout << time(NULL) - t << endl;
for(;;) { cout << "N » "; cin >> N; t = time(NULL);
if (N <= n ) { if (bit(N)) cout << "yes" << endl;
else cout << "no" << endl; continue; } if (N % 2 == 0)
{ cout << "no: " << N << " = 2·" << N / 2 << endl;
continue; } l = 1; m = ceil(sqrt(N)); for (i = 3;
i <= m; i+=2) if (bit(i)) if (N % i == 0) { l = 0;
cout << "no: " << N << " = " << i << "·" << N / i
<< endl; break; } if (l) cout << "yes" << " (" <<
time(NULL) - t << " seconds)" << endl; else
cout << "no" << endl; } }
В начале идёт формирование массива с информацией о простоте или непростоте всех беззнаковых четырёхбайтных целых чисел, коих больше четырёх миллиардов. Для хранения этого массива требуется более полугигабайта памяти, а само его формирование занимает на фаблете Samsung Galaxy чуть более шести с половиной минут, на стационарном же PC - намного быстрее! Зато при уже́ готовом массиве всё становится гораздо быстрее чем без него, особенно для девятнадцати- и двадцатизначных натуральных целых. Есть методы и ещё более быстрые чем этот, только для того, чтобы понять как они работают, требуется хотя бы элементарное знание теории чисел, а ещё лучше - продвинутое! Вот пример консольного сеанса на моём смартфоне:
Андрей Глинский Вы часом не профессор математики в Оксфорде?
Александр Кравченко Вон в самом конце else cout << "no" << endl; надо убрать - не нужно здесь этого писа́ть, а то в случае непростоты числа зачем-то два раза "no" выдаётся..
Андрей Глинский Диапазон не указан, зато указан алгоритм - переборный. Значит можно обойтись без этих математических штучек.
Александр Кравченко (◔‿◔) Надо же - «без этих математических штучек» ! Каково? Ну и ну!.
ʘ‿ʘ
Да, кстати, есть ещё вариант, только черезчур уж он жалкий, но для не очень больших чисел (в пределах, скажем, ста квадриллионов) вполне сойдёт:
#include <iostream>
#include <cmath>
using namespace std; int main()
{ int k, l, m; unsigned long long n;
while (true) { cout << "n » "; cin >> n;
if (n < 2) { cout << "no" << endl; continue; }
if (n == 2 || n == 3) { cout << "yes" << endl;
continue; } if (n % 2 == 0) { cout << "no, "
<< n << " = " << 2 << "·" << n / 2 << endl;
continue; } k = 1; m = ceil(sqrt(n));
for (l = 3; l <= m; l += 2) if (n % l == 0)
{ cout << "no, " << n << " = " << l << "·"
<< n / l << endl; k = 0; break; }
if (k) cout << "yes" << endl; } }