Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 给定一个数n,用最大偶数找到最接近它的素数_Python_Python 3.x - Fatal编程技术网

Python 给定一个数n,用最大偶数找到最接近它的素数

Python 给定一个数n,用最大偶数找到最接近它的素数,python,python-3.x,Python,Python 3.x,我有一个挑战,找到最接近任意给定整数n的素数,该整数具有最大偶数位数。下面的代码可以工作并通过所有示例测试。但当数字增长过大时,它就会超时。有人能建议我如何优化它吗 from collections import defaultdict def is_prime(n): first, i = 1, 2 if n <= first: return False while i <= (n**0.5): if n

我有一个挑战,找到最接近任意给定整数n的素数,该整数具有最大偶数位数。下面的代码可以工作并通过所有示例测试。但当数字增长过大时,它就会超时。有人能建议我如何优化它吗

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))

还有其他建议吗?谢谢

有非常聪明的方法来测试一个数字是否为素数(或者至少有聪明的方法可以精确到非常大的N),但是在这种情况下,当你计算到某个数字的所有素数时,你可以使用前面的素数,只检查它们作为因子:

def get_primes_list(n):
    if n < 2:
        return []
    primes = [2]
    for i in range(3,n+1):
        sqroot = i**0.5
        for p in primes:
            if i%p == 0:
                break
            if p > sqroot:
                primes.append(i)
                break
    return primes
def get_primes_列表(n):
如果n<2:
返回[]
素数=[2]
对于范围(3,n+1)内的i:
sqroot=i**0.5
对于素数中的p:
如果i%p==0:
打破
如果p>sqroot:
素数。附加(i)
打破
返回素数
如果您正在寻找比此更有效的方法(因为此方法仍然需要消耗资源,并且在达到数千万时仍需要很长时间),您最好的选择是找到一个有效的素性测试的现有实现,如前面提到的Rabin-Miller素性测试

使用“Eratosthenes筛”算法,生成小于N的素数

希望这能解决你的问题

它的时间复杂性:O(n*log(log(n))

参考资料:

有两个主要的优化领域,你应该考虑。 第一是确保我们的质数检查是合理的。从中采用智能暴力方法,基本上只需检查从1开始到数字平方根的所有n的
6n-1
6n+1
,以确定它是否为素数。(因为
6n+2
6n+4
是偶数,
6n+3
可以被3整除)。我在下面的
is_prime(n)
函数中添加了解释

第二个真正起作用的因素是确保始终跟踪“偶数位数的最佳结果”。想法很简单:
n
位的素数最多只能有
n-1
偶数,素数2除外。考虑到这一点,我们只需要确保找到可能的“最佳情况”,而不是将所有素数累加到给定的数
n
,我们只需找到适合最佳情况的最高素数,从大到小。因此,我有
highest\u prime\u 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
导入时间
def是_prime(n):
#基本案件处理
如果n==2或n==3:返回True#句柄2,3
如果n<2或n%2==0:返回False#处理1和偶数
如果n<9:return True#因为处理了1、2、3、4、6和8,所以剩下5和7。
如果n%3==0:返回False#处理3的倍数
r=int(n**0.5)#仅检查平方根
f=5#从5开始

当你在寻找正确方向的提示或解决方案时,你想要的是一个有效的解决方案。answer有一个Rabin Miller算法的Python实现,它应该会给您一点性能提升。您可能还想更仔细地了解一下您对
range
@paritossing的使用,正确的方向是fine@AndrewF如果我不反转射程,我会得到显著的提升吗?在这种情况下,我还需要将数据类型更改为有序dict。为什么素数测试效率不高,我只检查因子直到平方根。@KabirGandhiok我可以想出一种方法来切断需要检查偶数的素数的数量。这样说吧。。。一个2位素数最多可以有多少位是偶数?3号怎么样?等等(在你的例子中,第1209页可以被3整除。我猜这是错误的)这是一个有趣的关于素性检查的观点,尽管它仍然超时。对于非常大的数字,我需要在12000毫秒以下。我尝试了选择的答案,但它也超时了。@KabirGandhiok它并不意味着是最快的,只是改进了基本的暴力算法哇!太快了!!非常感谢你解释得这么好!
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