简体   繁体   English

如何改进此代码以提高时间效率? For循环,素数

[英]How to improve this code to make it time efficient? For-loops, prime numbers

The task was taken from www.codewars.com该任务取自www.codewars.com

The prime numbers are not regularly spaced.素数不是规则间隔的。 For example from 2 to 3 the step is 1. From 3 to 5 the step is 2. From 7 to 11 it is 4. Between 2 and 50 we have the following pairs of 2-steps primes:例如,从 2 到 3,步长为 1。从 3 到 5,步长为 2。从 7 到 11,步长为 4。在 2 到 50 之间,我们有以下成对的 2 步素数:

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

We will write a function step with parameters:我们将编写一个带有参数的 function 步骤:

g (integer >= 2) which indicates the step we are looking for, g (integer >= 2) 表示我们正在寻找的步骤,

m (integer >= 2) which gives the start of the search (m inclusive), m (integer >= 2) 给出搜索的开始(包括 m),

n (integer >= m) which gives the end of the search (n inclusive) n (integer >= m) 结束搜索(n 包括在内)

In the example above step(2, 2, 50) will return [3, 5] which is the first pair between 2 and 50 with a 2-steps.在上面的示例中, step(2, 2, 50) 将返回 [3, 5] ,它是 2 到 50 之间的第一对,有 2 步。

So this function should return the first pair of the two prime numbers spaced with a step of g between the limits m, n if these g-steps prime numbers exist otherwise nil or null or None or Nothing or [] or "0, 0" or {0, 0} or 0 0(depending on the language).所以这个 function 应该返回两个素数中的第一对,在限制 m 之间间隔 g 步长,n 如果这些 g 步素数存在,否则为 nil 或 null 或 None 或 Nothing 或 [] 或“0, 0”或 {0, 0} 或 0 0(取决于语言)。

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

step(2, 5, 5) --> nil or... or [] in Ocaml or {0, 0} in C++ step(2, 5, 5) --> nil or... or [] in Ocaml or {0, 0} in C++

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

See more examples for your language in "TESTS"在“测试”中查看您的语言的更多示例

Remarks: ([193, 197] is also such a 4-steps primes between 130 and 200 but it's not the first pair).备注:([193, 197] 也是 130 到 200 之间的这样一个 4 步素数,但它不是第一对)。

step(6, 100, 110) --> [101, 107] though there is a prime between 101 and 107 which is 103; step(6, 100, 110) --> [101, 107] 虽然在 101 和 107 之间有一个素数,即 103; the pair 101-103 is a 2-step. 101-103 对是 2 步。

Here is my solution, which works perfectly and takes more than it requires to test out, however, I'm trying to optimize this code in order to make it more time-efficient.这是我的解决方案,它运行良好,并且比测试所需的更多,但是,我正在尝试优化此代码以使其更省时。

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

If you have any suggestions or even sample code, I would appreciate this.如果您有任何建议甚至示例代码,我将不胜感激。

First things first, never use keywords as variables .首先,永远不要使用关键字作为变量

To come with a better approach, you need to think the flaws in your approach.要采用更好的方法,您需要考虑方法中的缺陷。

  1. You're iterating through all numbers to determine the prime numbers.您正在遍历所有数字以确定素数。
  2. You're iterating through the list in O(n**2) to find if a pair exists with the required difference.您正在遍历 O(n**2) 中的列表以查找是否存在具有所需差异的对。
  3. Your algorithm for prime number calculation is not optimal.您的素数计算算法不是最佳的。

For the 1st point, it is not even required to find all the primes in a given range, as your task to find first pair with the required difference .对于第一点,甚至不需要找到给定范围内的所有素数,因为您的任务是找到具有所需差异的第一对 So, if you find number a as a prime and a + g also a prime, then you found the solution already.所以,如果你发现数字a是素数并且a + g也是素数,那么你已经找到了解决方案。

For the 2nd point, you can simply iterate through the list, and check if (k + g) in list to find if you've found the pair.对于第二点,您可以简单地遍历列表,并检查列表中的if (k + g) in list以查找您是否找到了该对。

For the 3rd point, you can found an optimal implementation on the wikipedia page itself.对于第三点,您可以在 wikipedia 页面本身上找到最佳实现。 If you can understand the logic, then you may write that implementation yourself very easily.如果你能理解逻辑,那么你可以很容易地自己编写那个实现。

So, combining an optimal prime checking implementation with a single loop iteration, the solution can be easily written as shown below.因此,将最佳素数检查实现与单个循环迭代相结合,可以轻松编写解决方案,如下所示。

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

This implementation took only 1.32 sec for 1,000,000 iterations for step(4, 130, 200) .对于step(4, 130, 200)的 1,000,000 次迭代,此实现只用了 1.32 秒。 As you can see, the logic is very simple once you implement the is_prime function.如您所见,一旦您实现了is_prime function,逻辑就非常简单。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM