我很难找到最接近偶数最大的给定整数n的质数。下面的代码有效并通过了所有示例测试。但是,当数字太大时,它就会超时。谁能建议我如何优化它?
"Given xpath expression "//div[@class=inner-results firma]" is invalid: SyntaxError: The expression is not a legal expression."
测试1的期望值为887
测试2的期望值为1201
测试3的期望值为8887
编辑: 根据建议,由于一个数字中最大质数的总位数总是比总数字少一,因此,我只保留了那些长度与给定整数N相同的数字。足够。对于素数检查,我在isPrime Function for Python Language
使用了选定的答案from collections import defaultdict
def is_prime(n):
first, i = 1, 2
if n <= first:
return False
while i <= (n**0.5):
if n % i == 0:
return False
i += first
return True
def highest_prime(n):
dd = defaultdict(int)
nums = [str(x) for x in reversed(range(n)) if is_prime(x)]
is_even = (lambda x: x % 2 == 0)
for outer in nums:
for inner in outer:
if is_even(int(inner)):
dd[outer] += 1
return max(dd, key=lambda x: dd[x])
if __name__ == "__main__":
print(highest_prime(1000))
print(highest_prime(1210))
print(highest_prime(10000))
还有其他建议吗?谢谢!
答案 0 :(得分:2)
有很多非常聪明的方法可以测试一个数字是否为质数(或者至少聪明的方法可以校正一个非常大的N),但是在这种情况下,当您计算所有质数直到某个数字时,就可以使用以前的质数,仅检查它们是否为因数:
fromList (a:as) = a :| as
如果您正在寻找比此方法更有效的方法(由于该方法仍然消耗资源,并且当花费数千万美元时仍会花费很长时间),最好的选择是找到一个有效的现有方法像提到的Rabin-Miller素数测试一样的素数测试
答案 1 :(得分:1)
您应该考虑两个主要的优化领域。
首先要确保我们的素数检查正确。从Source采取聪明的暴力破解方法,您基本上只需要检查6n - 1
和6n + 1
中从1到数字平方根的所有n即可确定是素数还是素数。不。 (因为6n + 2
,6n + 4
是偶数,并且6n + 3
被3整除)。我在下面的is_prime(n)
函数中添加了解释。
真正起作用的第二个方面是确保始终跟踪“偶数位的最佳结果”。这个想法很简单:素数为n
的质数最多可以有n-1
个偶数,但素数2除外。考虑到这一点,我们只需要确保可以找到可能的“最佳情况”,而不是将所有素数累加到给定的数字n
,我们只是找到适合我们最佳情况的最高素数,从大到小。因此,我有highest_prime_optimized(n)
和评论。我最初计划将其时间与原始功能进行比较,但是一旦原始功能运行了一分钟,我便决定将其终止。这应该胜过测试。
import time
def is_prime(n):
#base cases handling
if n == 2 or n == 3: return True #handles 2, 3
if n < 2 or n%2 == 0: return False #handles 1 and even numbers
if n < 9: return True #since 1, 2, 3, 4, 6 and 8 are handled, this leaves 5 and 7.
if n%3 == 0: return False #handles multiples of 3
r = int(n**0.5) #only check upto square root
f = 5 #start from 5
while f <= r:
#print ('\t', f)
if n%f == 0: return False #essentially checks 6n - 1 for all n.
if n%(f+2) == 0: return False #essentially checks 6n + 1 for all n.
f +=6 #incrementing by 6.
return True
def max_even_digits_in_prime(n):
return (len(str(n)) - 1) or 1
def count_of_even_digits(n):
count = 0
for i in str(n):
count+= (int(i) % 2 == 0)
return count
def highest_prime_optimized(n):
best_case = (0, 0) #keeps track of highest best case number seen[1], and its count of even digits[0]
for x in range(n, 1, -1): #iterate in the reverse direction
#print(x)
if is_prime(x): #proceed for prime numbers
even_digits = count_of_even_digits(x)
max_even_digits = max_even_digits_in_prime(x)
if best_case[0] < even_digits: #update best number seen so far
best_case = (even_digits, x)
if max_even_digits == best_case[0]: #best case answer, your work is done. No need to look for more numbers.
print(best_case)
return (best_case[1])
if __name__ == "__main__":
print(highest_prime_optimized(1000))
print(highest_prime_optimized(1210))
print(highest_prime_optimized(10000))
start = time.time()
result = highest_prime_optimized(5000000)
print(result, time.time() - start)
#Output: 4888889 0.5920031070709229
答案 2 :(得分:0)
使用“ Eratosthenes筛子”算法,该算法生成小于N的素数。
希望这可以解决您的问题。
时间复杂度:O(n * log(log(n)))