对于这个问题,我需要在更大的数字中找到最大的素数。出于示例的目的,假设较大的数字是“123456789”,那么我需要检查的一些数字是12,456,234567等。
我写了一些Python代码来解决这个问题,但是对于我想要检查的数字,它的运行速度非常慢。我正在使用的实际数字大约是10000位数,所以我需要查看很多数字。这是我的代码:
num = "123456789"
def isPrime(n):
# 0 and 1 are not primes
if n < 2:
return False
# 2 is the only even prime number
if n == 2:
return True
# all other even numbers are not primes
if not n & 1:
return False
# range starts with 3 and only needs to go up the squareroot of n
# for all odd numbers
for x in range(3, long(n**0.5)+1, 2):
if n % x == 0:
return False
return True
def largestPrime():
largest = 2
for i in range(0,len(num)):
for j in range(i+1,len(num)):
if isPrime(long(num[i:j])):
if long(num[i:j]) > largest:
largest =long(num[i:j])
print largest
def main():
largestPrime()
main()
我很确定这段代码会给出正确的答案,但正如我所说,它真的很慢。任何人都可以帮我弄清楚如何加快速度吗?
感谢您的帮助!
答案 0 :(得分:3)
我可能会使用以总位数开头并查看是否为素数的策略。然后继续向左移动数字,同时向左移动以查看是否为素数。让我用一个例子来解释:
123456789
First check the 9-digit number: 123456789
Then check the 8-digit numbers: 23456789, 12345678
Then Check the 7-digit numbers: 3456789, 2345678, 1234567
etc.
答案 1 :(得分:1)
我看到的一个问题是,对于某些大数字,您将多次测试相同的数字。例如,对于'123456712345671234567',您的代码将测试'1234567'3次。我建议你制作一个不包含重复的集合,然后对每个数字进行主要测试。我也认为排序数字是一个好主意,因为我们可以在找到第一个素数后停止。
接下来,如果您正在处理大数字(例如10000位数),我建议使用统计素性测试。下面我使用来自wikipedia的伪代码进行了Miller-Rabin素性测试。
我几乎重写了你的代码:P
import random
num = '3456647867843652345683947582397589235623896514759283590867843652345683947582397589235623896514759283590784235876867843652345683947582397589235623896514759283590784235876867843652345683947582397589235623896514759283590784235876867843652345683947582397589235623896514759283590784235876867843652345683947582397589235623896514759283590784235876867843652345683947582397589235623896514759283590784235876867843652345683947582397589235623896514759283590784235876784235876324650'
def probablyPrime(num, k):
"""Using Miller-Rabin primality test"""
if num == 2 or num == 3:
return True
if num < 2:
return False
if not num & 1:
return False
# find s and d such that n−1 = (2**s)*d with d odd
d = (num-1) >> 1
s = 1
while not (d & 1):
d = d >> 1
s += 1
# run k times
for _ in range(k):
a = random.randint(2, num-2)
x = pow(a, d, num) # more efficient than x = a**d % num
if not (x == 1 or x == num-1):
for _ in range(s-1):
x = (x**2) % num
if x == 1:
return False
if x == num-1:
break
if not x == num-1:
return False
return True
def largestPrime(num):
num_list = set([])
for i in range(0,len(num)+1):
for j in range(i+1,len(num)+1):
inum = int(num[i:j])
# Don't append numbers that have already appeared
if inum not in num_list:
num_list.add(inum)
# Convert to list and sort
num_list = list(num_list)
num_list.sort(reverse=True)
for num in num_list:
print('Checking ' + str(num))
if probablyPrime(num,100):
print('\n' + str(num) + ' is probably the largest prime!')
return
largestPrime(num)
提高速度的另一种方法可能是python的multiprocessing包。
答案 2 :(得分:0)
<强>代码:强>
def isprime(n):
if n == 2:
return str(n)+" is the biggest prime"
if n % 2 == 0:
return isprime(n-1) #not prime, check again for next biggest number
max = n**0.5+1
i = 3
while i <= max:
if n % i == 0:
return isprime(n-1) #not prime, check again for next biggest number
i+=2
return str(n)+" is the biggest prime"
print "Testing 7:",isprime(7)
print "Testing 23:",isprime(23)
print "Testing 2245:",isprime(2245)
print "Testing 222457:",isprime(222457)
print "Testing 727245628:",isprime(727245628)
<强>输出:强>
>>>
Testing 7: 7 is the biggest prime
Testing 23: 23 is the biggest prime
Testing 2245: 2243 is the biggest prime
Testing 222457: 222437 is the biggest prime
Testing 727245628: 727245613 is the biggest prime