@Idwln

Как реализовать Алгоритм Решето Эратосфена от определенного числа, до данного?

У меня есть код Алгоритма Решето Эратосфена:
def primes(n):
        sieve = [True] * n
        for i in range(3, int(n ** 0.5) + 1, 2):
            if sieve[i]:
                sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
        return [2] + [i for i in range(3, n, 2) if sieve[i]]


Как мне его исправить так, чтобы если я вызываю эту функцию и передаю туда число 1000000000 поиск простых чисел начинался с числа 900000000. Сам не могу понять, ибо код Решето брал с интернета и для моих задач он не требовал изменений
  • Вопрос задан
  • 108 просмотров
Решения вопроса 1
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Решето Эратосфена всегда начинается с 2. Его принцип - на каждом шаге находим следующее невычеркнутое число, оно является простым. Для построения массива от 900000000 до 1000000000 необходимо вычеркнуть из этого массива все кратные простым числам от 2 до 500000000, а для этого надо эти простые найти.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
wataru
@wataru Куратор тега Алгоритмы
Разработчик на С++, экс-олимпиадник.
Раз уж я в коментариях к вопросу и так код привел (ради доказательства, что кто-то в интернете неправ), то приведу его и в качестве ответа. Код был на коленке ради быстрой проверки написан, поэтому в продакшн его так не пихайте. Глобальные переменные, константы - все это надо бы причесать.

const int BE = 900000000;
const int N = 1000000000;

std::vector<int> small_primes;

bool DivisibleBySmallPrimes(int x) {
	for (int i = 0; i < (int)small_primes.size() && small_primes[i]*small_primes[i] <= x; ++i) {
		if (x % small_primes[i] == 0) return true;
	}
	return false;
}

void ComputeSmallPrimes() {
	int n = sqrt(N);
	for (int i = 2; i <= n; ++i) {
		if (!DivisibleBySmallPrimes(i)) {
			small_primes.push_back(i);
		}
	}
}

void ComputeSieve() {
	ComputeSmallPrimes()
	std::vector<bool> sieve(N-BE+1);
	std::vector<int> primes;
	for (auto &x : small_primes) {
		int i = (BE-1) - (BE-1) % x + x;
		while (i <= N) {
			sieve[i-BE] = true;
			i += x;
		}
	}
	for (int i = BE; i <= N; ++i) {
		if(!sieve[i-BE]) {
			primes.push_back(i);
		}
	}
}


upd:
ComputeSmallPrimes можно переписать простым решетом - будет еще быстрее.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы