Простое число с резьбой

Я пишу код, чтобы напечатать все числа от начала до конца, которые пишет пользователь. Я хочу сделать это с потоками. Например, начало равно 1, а конец равен 100. Я прошу пользователей ввести число N, которое является числом потоков, создаваемых программой. Например, если он введет 10, программа создаст 10 потоков. Первый поток будет печатать число простых чисел от 1 до 10. Второй поток будет печатать число простых чисел от 10 до 20. Третий от 20 до 30 и сын на ..

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

Это мой код:

void writePrimesToFile(int begin, int end, ofstream&  file)
{
for (int i = begin; i <= end; i++)
{
for (int j = begin; j < end / 2; j++)
{
if (i % j != 0)
{
file << i << endl;
}

}
}
}

void callWritePrimesMultipleThreads(int begin, int end, string filePath, int N)
{
ofstream myfile(filePath);
clock_t startTimer, stopTimer;

startTimer = clock();

vector<thread> arr;

for (int i = 0; i < N; i++)
{
int start = begin;
int finish = N;
arr.emplace_back(writePrimesToFile, start, finish, ref(myfile));
start = finish;
finish += N;
}
for (auto& thread : arr)
{
thread.join();
}

stopTimer = clock();
cout << "The time that takes is: " << (double)(stopTimer - startTimer) / CLOCKS_PER_SEC << endl;
}

Код в основном:

    callWritePrimesMultipleThreads(1, 100, "primes2.txt", 10);

0

Решение

Много вещей, которые нужно исправить в вашем коде, простые числа начнутся с 1, а не с 0, также вы должны начать делить на 2, а не на 1 или 0 (вы не можете разделить на 0), после того как вы получите остаток 0 для одного, это не является простым, и оно всегда будет заканчиваться числом, которое вы хотите вычислить (10% 20 — это бессмысленно)

#include <stdio.h>
#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
#include <functional>
#include <fstream>
#include <math.h>

using namespace std;
mutex mtx;

void writePrimesToFile(unsigned int begin, unsigned int end, ofstream& f)
{
for (unsigned int i = begin; i <= end; i++)
{
for (unsigned int j = 2; j < i; j++)
{
if (i % j == 0)
{
break;
}
else if(j + 1 == i)
{
mtx.lock();
f << i << endl;
mtx.unlock();
}
}
}
}

void callWritePrimesMultipleThreads(unsigned int begin, unsigned int end, string filePath, unsigned int N)
{
ofstream myfile(filePath);
clock_t startTimer, stopTimer;

startTimer = clock();

vector<thread> arr;
unsigned int each = end/N;
unsigned int start = begin;
unsigned int finish = start + each - 1;
for (unsigned int i = 0; i < N; i++)
{
arr.emplace_back(writePrimesToFile, start, finish, ref(myfile));
start += each;
finish += each;
}
for (auto& thread : arr)
{
thread.join();
}

stopTimer = clock();
cout << "The time that takes is: " << (double)(stopTimer - startTimer) / CLOCKS_PER_SEC << endl;
}int main()
{
callWritePrimesMultipleThreads(1, 110, (string)"primes.txt", 10);
return 0;
}

Также добавлен мьютекс при записи в файл.

1

Другие решения

Посмотрите на вашу петлю:

for (int i = begin; i <= end; i++)
{
for (int j = begin; j < end / 2; j++)
{
if (i % j != 0)
{
file << i << endl;
}

}
}

Вы выводите i каждый раз Вы найдете число, на которое не делится.
Это много цифр.
(9, например, не делится на 2, 4, 5, 6, 7 или 8. Но это не простое число.)

Число простое, если оно не делится ни на какое число (> = 2), а не на число, на которое оно не делится.

Также недостаточно искать факторы между begin а также end / 2нужно посмотреть между 2 а также sqrt(end),

Мой совет — сначала написать работающий однопоточный тест на простоту, прежде чем начинать многопоточность и интервальную нарезку.

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector