1

Тема: Знаходження простих чисел перебором дільників і решето Ератосфена

Допоможіть, будь ласка, виконати ці завдання (проблему описав в кінці):
1) Реалізувати алгоритм знаходження простих чисел звичайним перебором
дільників, для цього створити функцію яка перевіряє одне число на
простоту: bool isPrime(int number) { ... }
Виконати задачу по варіанту, заміряти час роботи.
2) Реалізувати алгоритм «Решето Ератосфена» для знаходження всіх
простих чисел на проміжку від 1 до N. Виконати задачу по варіанту,
заміряти час роботи.
3) Перевірити правильність результатів роботи обох алгоритмів на різних
вхідних даних, порівняти їх швидкодію.
Завдання за моїм варіантом:
Знайти добуток найбільшого та найменшого трицифрових простих чисел.

Ось мій код:

#include <iostream>
#include <windows.h>
#include <locale.h>

using namespace std;

bool isPrime(int n)
{
    for (int i = 2; i <= sqrt(n); i++)
    {
        if (n % i == 0)
        {
            return false;
        }
    }
    return true;
}

int isPrimeE(int n)
{

    const int N = 1001;
    bool primeNumbers[N] = { true };
    primeNumbers[0] = primeNumbers[1] = false;
    for (int i = 2; i * i <= n; i++)
    {
        if (primeNumbers[i])
        {
            for (int j = i * i; j <= n; j += i)
            {
                primeNumbers[j] = false;
            }
        }
    }
    
}

int main()
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);

    int n;
    
    cout << "Введіть число: ";
    cin >> n;
    cout << isPrime(n) << endl;
    cout << isPrimeE(n) << endl;

    system("pause");
    return 0;
}

Проблема в тому, що функція "isPrimeE" (решето Ератосфена) працює не правильно і я не знаю в чому проблема і як це виправити (скоріше всього функція повинна щось повертати, а я не можу зрозуміти що саме, а може проблема і не в цьому, я вже заплутався). І ще я не можу зрозуміти як реалізувати завдання за моїм варіантом, особливо в першій функції, ідей взагалі немає.
Тому дуже прошу Вас про допомогу, буду щиро вдячний!

2

Re: Знаходження простих чисел перебором дільників і решето Ератосфена

void isPrimeE(int n)
{
   vector<int> primeNumbers(n);
   for(int i = 2; i < n; i++)
      primeNumbers[i] = i;

   for (int i = 0; i * i < n; i++)
   {
      if (primeNumbers[i])
      {
         for (int j = i * i; j < n; j += i)
         {
            primeNumbers[j] = 0;
         }
      }
   }

   primeNumbers.erase(remove(primeNumbers.begin(), primeNumbers.end(), 0), primeNumbers.end());
   for(int el: primeNumbers)
      cout << el << " ";
}

треба підключити вектор і алгоритм

3

Re: Знаходження простих чисел перебором дільників і решето Ератосфена

Для того, щоб скористатися решетом Ератосфена, вам треба зробити дві окремі дії (їх можна, за бажання, оформити окремими функціями). Спершу вам треба один раз обчислити решето (масив bool) і десь зберегти, щоб мати доступ (наприклад, у глобальній змінній). Далі, коли вам треба перевірити будь-яке число на простоту, треба лише подивитися значення в цьому масиві за відповідним індексом.

Подякували: leofun011

4

Re: Знаходження простих чисел перебором дільників і решето Ератосфена

Бібліотею <vector> користуватися, на жаль, заборонено, потрібно якось без неї зробити решето Ератосфена

Olex_V написав:
void isPrimeE(int n)
{
   vector<int> primeNumbers(n);
   for(int i = 2; i < n; i++)
      primeNumbers[i] = i;

   for (int i = 0; i * i < n; i++)
   {
      if (primeNumbers[i])
      {
         for (int j = i * i; j < n; j += i)
         {
            primeNumbers[j] = 0;
         }
      }
   }

   primeNumbers.erase(remove(primeNumbers.begin(), primeNumbers.end(), 0), primeNumbers.end());
   for(int el: primeNumbers)
      cout << el << " ";
}

треба підключити вектор і алгоритм

5

Re: Знаходження простих чисел перебором дільників і решето Ератосфена

Можете, будь ласка, зробити це в коді, бо в мене щось ніяк не виходить реалізувати Вашу задумку в моєму коді. Буду дуже вдячний.

koala написав:

Для того, щоб скористатися решетом Ератосфена, вам треба зробити дві окремі дії (їх можна, за бажання, оформити окремими функціями). Спершу вам треба один раз обчислити решето (масив bool) і десь зберегти, щоб мати доступ (наприклад, у глобальній змінній). Далі, коли вам треба перевірити будь-яке число на простоту, треба лише подивитися значення в цьому масиві за відповідним індексом.

6

Re: Знаходження простих чисел перебором дільників і решето Ератосфена

Показуйте, що вийшло.

7

Re: Знаходження простих чисел перебором дільників і решето Ератосфена

Завдяки koala та матеріалу із Вікіпедії https://uk.wikipedia.org/wiki/%D0%A0%D0 … 0%BD%D0%B0

// exp_010.cpp : 
// Реалізувати алгоритм «Решето Ератосфена» для знаходження всіх
// простих чисел на проміжку від 1 до N.Виконати задачу по варіанту,
// заміряти час роботи.


#include <iostream>
#include <cmath>

bool isPrimeE(size_t);
void FillArray();

const size_t MAXN = 1000;
bool primeNumbers[MAXN] = { true };

int main()
{
    for (size_t i = 0; i < MAXN; i++)
    {
        primeNumbers[i] = true;
    }
    std::cout << "Hello World!\n";
    FillArray();
    for (size_t i = 2; i < 77; i++)
    {

        std::cout << "value=" << i << " isPrimeE = " << isPrimeE(i) << std::endl; //"\t";
    }
    std::getchar();
}

bool isPrimeE(size_t n)
{
    return primeNumbers[n];
}

void FillArray()
{
    size_t len = (size_t)std::ceil(std::sqrt(MAXN));
    size_t j = 0;
    primeNumbers[0] = primeNumbers[1] = false;
    for (size_t i = 2; i < len; i++)
    {        
        if ( primeNumbers[i] )
        {
            j = i * i;            
            while (j < MAXN)
            {
                primeNumbers[j] = false;
                j += i;                
            }
        }
    }
}
Подякували: koala1

8

Re: Знаходження простих чисел перебором дільників і решето Ератосфена

Дякую всім за допомогу!

koala написав:

Показуйте, що вийшло.

Код трохи переробив з урахуванням усіх своїх завдань:

#include <iostream>
#include <cmath>
#include <ctime>
#include <clocale>
#include <windows.h>

using namespace std;

bool isPrime(int n)
{
    for (int i = 2; i < sqrt(n) + 1; ++i)
        if (n % i == 0) {
            return false;
        }
    return true;
}

int main()
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);

    clock_t startTime = clock();
    int lprime, rprime;
    int i = 100;
    for (int t = 0; t < 100000; t++) {
        for (; i < 1000; ++i)
            if (isPrime(i)) {
                lprime = i;
                break;
            }
        for (int j = 999; j >= i; --j)
            if (isPrime(j)) {
                rprime = j;
                break;
            }
    }
    clock_t endTime = clock();
    double seconds = (double(endTime - startTime)) / CLOCKS_PER_SEC;
    cout << "Час алгоритму знаходження простих чисел перебором дільників: " << seconds << endl;
    cout << "Найбільше та наймеше трицифрові прості чисела, знайдені перебором дільників: " << lprime << ' ' << rprime << endl;
    cout << "Добуток найбільшого та наймешого трицифрових простих чисел: " << lprime * rprime << endl;
    lprime = rprime = 0;

    clock_t startTimeE = clock();
    const int N = 1000;
    bool primeNumbers[N];
    for (int t = 0; t < 100000; t++) {
        for (int i = 0; i < N; ++i)
            primeNumbers[i] = true;
        primeNumbers[0] = primeNumbers[1] = false;
        for (int i = 2; (i * i) < N; ++i) {
            if (primeNumbers[i])
                for (int j = i + i; j < N; j += i)
                    primeNumbers[j] = false;
        }
        for (i = 100; i < 1000; ++i)
            if (primeNumbers[i]) {
                lprime = i;
                break;
            }
        for (int j = 999; j >= i; --j)
            if (primeNumbers[j]) {
                rprime = j;
                break;
            }
    }
    clock_t endTimeE = clock();
    double secondsE = (double(endTimeE - startTimeE)) / CLOCKS_PER_SEC;
    cout << "\nЧас алгоритму «Решето Ератосфена»: " << secondsE << endl;
    cout << "Найбільше та наймеше трицифрові прості чисела, знайдені решетом Ератосфена: " << lprime << ' ' << rprime << endl;
    cout << "Добуток найбільшого та наймешого трицифрових простих чисел: " << lprime * rprime << endl;

    int n;
    cout << "\nПеревірка числа на простоту\nВведіть число: ";
    cin >> n;
    cout << isPrime(n) << " (Перебір дільників)" << endl;
    cout << primeNumbers[n] << " (Решето Ератосфена)" << endl;

    return 0;
}

Якщо Ви помітите можливі помилки або неправильний запис рядків коду, напишіть, будь ласка, про це. Буду вдячний за будь-яку допомогу.