Sieve of Eratosthenes 알고리즘을 사용하여 소수 생성기를 구현하려고합니다. sifter를 구현하기 위해 재귀적인 iterator merging을 사용하려고합니다.병합 된 반복자가 모호한 결과를 생성합니다.
은 내가하는 일은 이것이다 :
from itertools import count,islice,groupby
from heapq import merge
def primes3():
p = 2
yield p
sifter = (i*p for i in count(p))
s = next(sifter)
for p in count(p+1):
if p==s: # this p is sieved out
print('s: {}'.format(s))
s = next(sifter)
else:
yield p # this is prime
print('p: {}'.format(p))
sifter = (k for k, g in groupby(merge(sifter,(i*p for i in count(p))))) #add this serie to the sifter: p*p, p*(p+1), p*(p+2), ...
print(list(islice(primes3(),10)))
출력은 다음과 같습니다
p: 3
s: 4
p: 5
p: 6
p: 7
p: 8
p: 9
p: 10
p: 11
s: 12
[2, 3, 5, 6, 7, 8, 9, 10, 11, 13]
첫 번째 숫자는 4
가 밖으로 체질 될 수 있습니다. 그러나 다음은 12
이 아니고 6
이 아니어야합니다. 왜 그런가요? 나는 다음과 같은 코드로 확인 :
>>> sifter = (i*2 for i in count(2))
>>> next(sifter)
4
>>> sifter = (k for k, g in groupby(merge(sifter,(i*3 for i in count(3)))))
>>> print(list(islice(sifter,20)))
[6, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 22, 24, 26, 27, 28, 30, 32, 33, 34]
그래서, 우리는 체로 정확한 결과를 산출 시험 조건에서 볼 수있다.
어디에서 실수합니까? 나는 그것이 단지 보지 못하는 사소한 것이어야한다고 생각한다.
고마워요! 당신의 도움이 없었다면 나는 틀린 것을 발견 할 것입니다! – ovgolovin
질문이 하나 더 있습니다. 거기에 특별한 함수를 만드는 것과는 별도로 p에 대한 로컬 범위를 만들 수있는 또 다른 방법이 있습니까 (함수 호출은 다소 느립니다). – ovgolovin
'gensifter' 함수에 또 다른 해결책을 찾았습니다 :'count (p * p, p)'(첫 번째 매개 변수는 시작 값이고 두 번째 매개 변수는 단계 임) – ovgolovin