Python 谁能教我如何进一步优化这个';打印到第n个素数';剧本
我今年17岁,在Python编程语言的帮助下开始编程 我一直在寻求优化这个算法,也许是通过消除其中一个循环,或者通过更好的测试来检查素数 试图计算和显示100000个素数时,脚本会暂停约6秒,因为它会在素数列表作为输出返回控制台之前用素数填充列表 我一直在尝试使用Python 谁能教我如何进一步优化这个';打印到第n个素数';剧本,python,algorithm,optimization,performance,numbers,Python,Algorithm,Optimization,Performance,Numbers,我今年17岁,在Python编程语言的帮助下开始编程 我一直在寻求优化这个算法,也许是通过消除其中一个循环,或者通过更好的测试来检查素数 试图计算和显示100000个素数时,脚本会暂停约6秒,因为它会在素数列表作为输出返回控制台之前用素数填充列表 我一直在尝试使用 print odd, 为了简单地打印每个找到的素数,对于较小的输入(如n=1000)来说速度更快,但是对于n=1000000,列表本身的打印速度要快得多(在pythonshell和控制台中) 也许整个代码/算法都应该修改,但脚本应该
print odd,
为了简单地打印每个找到的素数,对于较小的输入(如n=1000)来说速度更快,但是对于n=1000000,列表本身的打印速度要快得多(在pythonshell和控制台中)
也许整个代码/算法都应该修改,但脚本应该基本保持不变:用户键入要打印的素数(n),脚本返回所有素数,直到第n个素数
from time import time
odd = 1
primes = [2]
n = input("Number of prime numbers to print: ")
clock = time()
def isPrime(number):
global primes
for i in primes:
if i*i > number:
return True
if number%i is 0:
return False
while len(primes) < n:
odd += 2
if isPrime(odd):
primes += [odd]
print primes
clock -= time()
print "\n", -clock
raw_input()
从时间导入时间
奇数=1
素数=[2]
n=输入(“要打印的素数:”)
时钟=时间()
def iPrime(编号):
全局素数
对于素数中的i:
如果i*i>编号:
返回真值
如果编号%i为0:
返回错误
而len(素数)
我可能想重写整个脚本,使用类似Atkin的筛子:
然而,我只是Python的初学者(甚至是编程方面的初学者:我两周前才开始编写代码),要想弄清楚如何用Python编写Atkin算法的筛选,对我来说是一个相当大的挑战
我希望有一个谷歌黑客能帮我解决这样的问题:(一个简单的优化,可以在不完全破解代码的情况下应用
- 随着列表变长,每个素数上的i*i变得非常浪费。相反,在循环外计算i的平方根,并在循环内根据该值进行测试
max
)设置为2max+1
到max+n
的n
连续数字列表from math import sqrt
from time import time
primes = [2]
max = 3
n = input("Number of prime numbers to print: ")
r=2
clock = time()
def sieve(r):
global primes
global max
s = set(range(max,max+r))
for i in primes:
b=max//i
if (b*i<max):
b=b+1
b=b*i
while b<=max+r-1:
if b in s:
s.remove(b)
b=b+i
for i in s:
primes.append(i)
while len(primes) < n:
r=primes[-1]
sieve(r)
max=max+r
primes=primes[0:n]
print primes
clock -= time()
print "\n", -clock
raw_input()
从数学导入sqrt
从时间导入时间
素数=[2]
最大值=3
n=输入(“要打印的素数:”)
r=2
时钟=时间()
def筛(r):
全局素数
全局最大值
s=设定值(范围(最大值,最大值+r))
对于素数中的i:
b=最大值//i
如果(b*i任何以5结尾的数字,而不是5,都不是素数。所以你可以用一个语句跳过任何以5结尾的大于5的数字。正如魏子尧已经说过的那样,我也会尝试一个筛子实现。我唯一要改进的是将其作为所用大小的起点
在纯python中计算逆函数并不简单,但迭代方法应该足够好,这样你就可以很好地了解筛子必须有多大。因为我不太记得定理的详细证明,而且现在是早上6点,其他人必须插手说如果该定理保证了可用于使用简单筛而不必担心其增长的任何特定上边界。不幸的是,事实并非如此。如前所述,所提出的算法无法显著改进。如果要求快速解决方案,则埃拉托斯筛是合适的。尺寸x>=55
,则筛的de>x可使用n>=x/(Lnx+2)
进行计算。该方程可使用牛顿迭代法进行求解。提出的算法比原始算法快约10倍:
def sieveSize(n):
# computes x such that pi(x) >= n (assumes x >= 55)
x = 1.5 * n # start
y = x - n * math.log(x) - 2 * n
while abs(y) > 0.1:
derivative = 1 - n/x
x = x - y / derivative
y = x - n * math.log(x) - 2 * n
return int(x) + 1
def eratosthenes(n):
# create a string flags: flags[i]=='1' iff i prime
size = sieveSize(n)
flags = ['1'] * size # start with: all numbers are prime
flags[0] = flags[1] = '0' # 0 and 1 are not primes
i = 0
while i * i < size:
if flags[i] == '1':
for j in range(i * i, size, i):
flags[j] = '0'
i += 1
return flags
def primes(n):
flags = eratosthenes(n)
prims = []
for i in range(0, len(flags)):
if flags[i] == '1':
prims.append(i)
return prims
prims = primes(100000)
def-sieveSize(n):
#计算x,使pi(x)>=n(假设x>=55)
x=1.5*n#开始
y=x-n*math.log(x)-2*n
当abs(y)>0.1时:
导数=1-n/x
x=x-y/导数
y=x-n*math.log(x)-2*n
返回int(x)+1
def埃拉托斯坦(n):
#创建一个字符串flags:flags[i]=“1”iff i prime
尺寸=筛分尺寸(n)
flags=['1']*size#开头:所有数字都是素数
标志[0]=标志[1]='0'#0和1不是素数
i=0
而i*i
这是一个很好的问题,但我认为它更适合codereview.stackexchange.com。堆栈溢出主要用于有明确答案的特定编程问题。我只是尝试计算sqrt(数字)