В Википедии это один из заданных алгоритмов для генерации простых чисел:
def eratosthenes_sieve(n):
# Create a candidate list within which non-primes will be
# marked as None; only candidates below sqrt(n) need be checked.
candidates = [i for i in range(n + 1)]
fin = int(n ** 0.5)
# Loop over the candidates, marking out each multiple.
for i in range(2, fin + 1):
if not candidates[i]:
continue
candidates[i + i::i] = [None] * (n // i - 1)
# Filter out non-primes and return the list.
return [i for i in candidates[2:] if i]
Я немного изменил алгоритм.
def eratosthenes_sieve(n):
# Create a candidate list within which non-primes will be
# marked as None; only candidates below sqrt(n) need be checked.
candidates = [i for i in range(n + 1)]
fin = int(n ** 0.5)
# Loop over the candidates, marking out each multiple.
candidates[4::2] = [None] * (n // 2 - 1)
for i in range(3, fin + 1, 2):
if not candidates[i]:
continue
candidates[i + i::i] = [None] * (n // i - 1)
# Filter out non-primes and return the list.
return [i for i in candidates[2:] if i]
Я впервые отметилот всех кратных 2, а затем я рассмотрел только нечетные числа.Когда я рассчитывал оба алгоритма (пробовал 40.000.000), первый всегда был лучше (хотя и немного).Я не понимаю почему.Может кто-нибудь объяснить, пожалуйста?
PS: Когда я пытаюсь 100.000.000, мой компьютер зависает.Это почему?У меня есть Core Duo E8500, 4 ГБ ОЗУ, Windows 7 Pro 64 бит.
Обновление 1: Это Python 3.
Обновление 2: Вот как я рассчитал время:
start = time.time()
a = eratosthenes_sieve(40000000)
end = time.time()
print(end - start)
ОБНОВЛЕНИЕ: После ценных комментариев (особенно Nightcracker и Winston Ewert) мне удалось сначала написать то, что я намеревался:
def eratosthenes_sieve(n):
# Create a candidate list within which non-primes will be
# marked as None; only c below sqrt(n) need be checked.
c = [i for i in range(3, n + 1, 2)]
fin = int(n ** 0.5) // 2
# Loop over the c, marking out each multiple.
for i in range(fin):
if not c[i]:
continue
c[c[i] + i::c[i]] = [None] * ((n // c[i]) - (n // (2 * c[i])) - 1)
# Filter out non-primes and return the list.
return [2] + [i for i in c if i]
Этот алгоритм улучшает оригинальный алгоритм (упоминается сверху) (обычно) на 50%.(Тем не менее, это хуже, чем алгоритм, упомянутый nightcracker, естественно).
Вопрос к Python Masters: есть ли более Pythonic способ выразить этот последний код более «функциональным» способом?
ОБНОВЛЕНИЕ 2: Я все еще не смог расшифровать алгоритм, упомянутый Nightcracker.Я думаю, что я слишком глуп.