我正在尝试解决此处提到的问题:https://www.spoj.pl/problems/PRIME1/
我也在下面给出描述。
彼得想为他的密码系统生成一些素数。帮助他!你的任务是生成两个给定数字之间的所有素数!
输入
输入以单行中的测试用例的数量t开始(t <= 10)。在下一个t行的每一行中,有两个数字m和n(1 <= m <= n <= 1000000000,n-m <= 100000)由空格分隔。
输出
对于每个测试用例,打印所有素数p,使得m <= p <= n,每行一个数,由空行分隔的测试用例。
我的代码如下。我在想列表上的删除方法很慢。
import sys
import math
num = int(sys.stdin.readline());
indices = []
maxrange = 2
while(num > 0):
a,b = sys.stdin.readline().split(" ");
a = int(a)
b = int(b)
if(a < 2):
a = 2
indices.append((a,b))
if(b > maxrange):
maxrange= b
num = num - 1
val = int(math.sqrt(maxrange)+1)
val2 = int(math.sqrt(val)+1)
checks = range(2,val2)
for i in range(2,val2):
for j in checks:
if(i!= j and j%i == 0):
checks.remove(j)
primes = range(2,val)
for i in checks:
for j in primes:
if(i != j and j%i == 0):
primes.remove(j)
primes2 = range(2,maxrange)
for i in primes:
for j in primes2:
if(j != i and j%i == 0):
primes2.remove(j)
for (a,b) in indices:
for p in primes2:
if(a<= p and b >= p):
print p
if(p > b):
break
print
我认为删除python列表非常慢。我的代码是正确的但我超时限制。有人可以帮我改进这段代码。
答案 0 :(得分:3)
素性测试功能表现最佳。 Miller-Rabin wikipedia page
上有伪代码答案 1 :(得分:2)
为什么不用一些标记值替换它,而不是删除不是素数的元素,可能是-1
或None
?然后在打印时,只需打印非标记的值。
使用长度为(n-m)
的列表,然后数字i
的索引为x[m+i]
。
答案 2 :(得分:1)
remove()在宏观方案中并不慢,只是代码称之为很多。
正如dappawit建议的那样,不是修改列表,而是更改列表中的值,以便您知道它不是一个有效的数字。
我也看到当你生成素数集时,你使用range(2,maxrange)
这是可以的,但如果下界远大于2则效率不高。你将浪费计算时间来生成素数甚至与问题空间无关。如果不出意外,请跟踪minrange和maxrange。
原始代码的一个错误是您使用range(2,maxrange)
。这意味着maxrange
不在所考虑的数字列表中。尝试使用3 5
作为a和b的输入来查看错误。
range(2,maxrange+1)
解决了这个问题。
代码中的另一个错误是您修改了原始序列:
修改循环中迭代的序列是不安全的(这只能发生在可变序列类型中,例如列表)。如果您需要修改正在迭代的列表(例如,复制所选项目),则必须迭代副本。切片表示法使这特别方便:
我的python技能很简陋,但这似乎有效:
旧:
primes2 = range(2,maxrange)
for i in primes:
for j in primes2:
if(j != i and j%i == 0):
primes2.remove(j)
for (a,b) in indices:
for p in primes2:
if(a<= p and b >= p):
新:
primes2 = array.array('L', range(minrange,maxrange+1))
for i in primes:
for j in primes2:
if(j != i and j%i == 0):
primes2[j-minrange] = 0
for (a,b) in indices:
for p in primes2:
if (p != 0):
if(a<= p and b >= p):
您还可以跳过生成素数集并直接测试数字,如果您必须生成素数的数字集不重叠(没有工作重复),这将起作用。 enter link description here
答案 3 :(得分:1)
这是Python中小奇数整数Miller–Rabin primality test的确定性变体:
from math import log
def isprime(n):
assert 1 < n < 4759123141 and n % 2 != 0, n
# (n-1) == 2**s * d
s = 0
d = n-1
while d & 1 == 0:
s += 1
d >>= 1
assert d % 2 != 0 and (n-1) == d*2**s
for a in [2, 7, 61]:
if not 2 <= a <= min(n-1, int(2*log(n)**2)):
break
if (pow(a, d, n) != 1 and
all(pow(a, d*2**r, n) != (n-1) for r in xrange(s))):
return False
return True
代码意图是可执行的伪代码。