【问题标题】:How to improve this code to make it time efficient? For-loops, prime numbers如何改进此代码以提高时间效率? For循环,素数
【发布时间】:2021-05-29 10:33:36
【问题描述】:

任务取自www.codewars.com

素数不规则间隔。例如从 2 到 3 步长是 1。从 3 到 5 步长是 2。从​​ 7 到 11 是 4。 在 2 到 50 之间,我们有以下成对的 2 步素数:

3, 5 - 5, 7, - 11, 13, - 17, 19, - 29, 31, - 41, 43

我们将编写一个带参数的函数步骤:

g (integer >= 2) 表示我们正在寻找的步骤,

m (integer >= 2) 给出搜索的开始(包括 m),

n (integer >= m) 结束搜索(n 包括在内)

在上面的示例中,step(2, 2, 50) 将返回 [3, 5],即 2 到 50 之间的第一对,分 2 步。

所以这个函数应该返回两个素数中的第一对 如果这些 g 步为素数,则在限制 m 之间以 g 步长间隔 数字存在,否则为 nil 或 null 或 None 或 Nothing 或 [] 或 "0, 0" 或 {0, 0} 或 0 0(取决于语言)。

例子:step(2, 5, 7) --> [5, 7] or (5, 7) or {5, 7} or "5 7"

step(2, 5, 5) --> nil 或 ... 或 Ocaml 中的 [] 或 C++ 中的 {0, 0}

step(4, 130, 200) --> [163, 167] or (163, 167) or {163, 167}

在“测试”中查看您的语言的更多示例

备注:([193, 197] 也是这样一个130到200之间的4步素数 但它不是第一对)。

step(6, 100, 110) --> [101, 107] 虽然在 101 之间有一个素数 和 107 是 103; 101-103 对是 2 步。

这是我的解决方案,它运行良好,需要的时间比测试所需的要多,但是,我正在尝试优化此代码以使其更省时。

def step(g,m,n):

    count = 0
    list= []
    list2 = []
    for num in range(m,n+1):
        if all(num%i!=0 for i in range(2,num)):
            count += 1
            list.append(num)
    

        
    for k in list:
        for q in list:
            if (q-k) > 0:
                if (q-k) == g:
                    list2.append(k)
                    list2.append(q)
            

                
    if not list2:
         return 
    else:
         return  [list2[0],list2[1]]

如果您有任何建议甚至是示例代码,我将不胜感激。

【问题讨论】:

    标签: python list for-loop if-statement primes


    【解决方案1】:

    首先,永远不要将关键字用作变量

    要采用更好的方法,您需要考虑方法中的缺陷。

    1. 您正在遍历所有数字以确定素数。
    2. 您在 O(n**2) 中遍历列表以查找是否存在具有所需差异的对。
    3. 您的素数计算算法不是最优的。

    对于第一点,甚至不需要找到给定范围内的所有素数,因为您的任务是找到具有所需差异的第一对。所以,如果你找到数字 a 是素数,a + g 也是素数,那么您已经找到了解决方案。

    对于第二点,您可以简单地遍历列表,然后检查 if (k + g) in list 以查找您是否找到了这对。

    对于第 3 点,您可以在 wikipedia 页面本身上找到最佳实现。如果你能理解逻辑,那么你可以很容易地自己编写那个实现。

    因此,将最优素数检查实现与单次循环迭代相结合,可以轻松编写出如下所示的解决方案。

    from functools import lru_cache
    
    @lru_cache(None)
    def is_prime(n):
        if n <= 3:
            return n > 1
        if n % 2 == 0 or n % 3 == 0:
            return False
        i = 5
        while i ** i <= n:
            if n % i == 0 or n % (i + 2) == 0:
                return False
            i += 6
        return True
    
    
    def step(g, m, n):
        for i in range(m, n + 1 - g):
            if is_prime(i) and is_prime(i + g):
                return [i, i + g]
        return
    

    step(4, 130, 200) 的 1,000,000 次迭代仅用了 1.32 秒。如您所见,实现is_prime函数后,逻辑非常简单。

    【讨论】:

    • 亲爱的 Naveen,我使用了你的算法,效果很好。但是,我通过以下方式更改了 is_prime 函数:` if all(n%i!=0 for i in range(2,n)): return True else: False `
    猜你喜欢
    • 2017-06-25
    • 2019-11-06
    • 1970-01-01
    • 1970-01-01
    • 2019-03-07
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    相关资源
    最近更新 更多