寻找数字的算法

时间:2018-09-07 12:37:05

标签: python algorithm recursion data-structures primes

编写一个枚举优势素数的递归算法。您的算法应在找到质数时将其打印出来(而不是在末尾)默认情况下,我们将要查找的质数限制为最大值10 ^ 12,预期运行时间应在或少于一分钟

以下是我的python代码,无法正常运行:

import math
def test_prime(n):
    k = 2
    maxk = int(math.sqrt(n))
    while k <= maxk:
        if n % k == 0:
            return False
        if k == 2:
            k += 1
        else:
            k += 2
    return (n is not 1)


def dominant_prime_finder(maxprime=10**12,n=1):
    l = 1    #length of the current number
    while n // 10 > 0:
        l += 1
        n //= 10
    if test_prime(n) == True:
        is_dominant_prime = True
        index_smaller = n
        while l > 1 and index_smaller > 9:
            index_smaller //= 10
            if test_prime(index_smaller) == False:
                is_dominant_prime = False
                break
        for i in range(1,10):
            if test_prime(i*10**l + n) == True:
                is_dominant_prime = False
                break
        if is_dominant_prime == True:
            print(n)
    while n <= maxprime:
        dominant_prime_finder()

3 个答案:

答案 0 :(得分:4)

您可以解决问题而无需枚举10 ^ 12以下的所有数字,这可以通过对数字的长度进行递归来降低效率。

它以下列方式工作:

  • 长度1的素数是:2,3,5,7。
  • 对于所有这些数字,请检查第三个条件,对于任何数字dn+1∈{1,…,9}dn+1dn…d0都不是质数。对于2没关系。对于3失败(例如13)。 在列表L中存储找到的所有素数。对长度为1的所有素数执行此操作。
  • 在L中,您现在拥有长度2的所有素数,并且以素数作为第一位数字,因此,您具有长度2的优势素数的所有候选项

以python递归的方式获得所有主导质数:

def test_prime(n):
    k = 2
    maxk = int(math.sqrt(n))
    while k <= maxk:
        if n % k == 0:
            return False
        if k == 2:
            k += 1
        else:
            k += 2
    return (n is not 1)

def check_add_digit(number,length):
    res = []
    for i in range(1,10):
        if test_prime( i*10**(length) + number ):
            res.append(i*10**(length) + number)
    return res

def one_step(list_prime,length): 
    ## Under 10^12 
    if length > 12:
        return None

    for prime in list_prime: 

        res = check_add_digit(prime,length)

        if len(res) == 0:
            #We have a dominant prime stop 
            print(prime)
        else:
            #We do not have a dominant prime but a list of candidates for length +1
            one_step(res,length+1)

one_step([2,3,5,7], length=1)

这可以在一分钟内在我的机器上运行。

答案 1 :(得分:2)

嗯,这段代码有几个问题:

  1. 您可以在开头({{1})处修改原始n。这基本上使n始终为一位。请改用另一个变量: n //= 10
  2. 您的递归调用不会更新n,因此您将进入无限循环: m = n while m // 10 > 0: l += 1 m //= 10 用。。。来代替: while n <= maxprime: dominant_prime_finder()
  3. 即使解决了这些问题,您也会因为主要质数相距甚远(2、5、3733、59399 ...)而导致堆栈溢出。因此,不要使用递归方法,而要使用例如生成器:

    
    if n <= maxprime:
        dominant_prime_finder(maxprime, n + 1)
    

答案 2 :(得分:0)

这个问题很酷。这是我们如何详细说明递归的方法:

def dominant_prime_finder(maxprime=10**12):
  def f(n):
    if n > maxprime:
      return

    is_dominant = True
    power = 10**(math.floor(math.log(n, 10)) + 1)

    for d in xrange(1, 10):
      candidate = d * power + n

      if test_prime(candidate):
        f(candidate)
        is_dominant = False

    if is_dominant:
      print int(n)

  for i in [2,3,5,7]: 
    f(i)