给定和整数,返回下一个整数,即素数和回文。蟒蛇

时间:2014-08-14 04:00:32

标签: python

给定任意随机整数,创建一个函数来查找下一个素数,即素数和回文数。

我的尝试

def golf(number):
    x = number + 1
    for i in range(2, x):
        if x % i == 0 or str(x) != str(x)[::-1]:
            golf(number + 1)
    return x
高尔夫(13)= 101

我实际上正在寻找一种替代选项而不是我使用的递归方法。如何在不使用递归的情况下实现最佳效果?

谢谢

5 个答案:

答案 0 :(得分:1)

Palindrome是一组比素数更稀疏的数字,你可以直接生成回文。

考虑序列98.102

这些是您可以基于这些

的基数

989,9889,999,9999,10001,100100,10101,1010110,10201,102201

ADDED

并非所有具有奇数位数的palidromes都会出现在具有偶数位数的palidromes之前。

如果你把它写成一个生成器(即使用yield),得到一个简单的算法来按顺序生成回文数。

对于1..9,您可以生成9或18个回文,具体取决于您是否考虑1位数的回文。

对于10..99,你会产生90个偶数和90个数字的回文。

对于100..999,您可以生成900个偶数位和900个奇数位的回文。

您刚刚生成的所有1989年(或1997年,如果包括单位数字)的回文数字少于100万。有78,498个素数小于100万

任何基于生成素数然后测试回文的算法都会慢得多,因为它会产生回文然后测试素数

答案 1 :(得分:1)

以下是byron he's answer的变体,它增加了几项优化:

  1. 在进行任何精心测试之前,我们可以消除所有偶数x值(除2之外),因为我们可以轻易地告诉他们不是素数。
  2. 一个小的改进是只调用str(x)一次,然后重用该值。
  3. 我们可以利用这样一个事实,即所有偶数长度的回文都是11的倍数,这意味着(除了11本身)它们不是素数。我们可以跳到下一个奇长x值。
  4. 由于我们已经消除了偶数,我们的主要测试只需要测试奇数除数。此外,当我们到达sqrt(x)时,我们可以停止循环,而不是一直到x本身。
  5. 最后,不需要使用布尔标志变量来传递循环中的素数。如果我们不break,则会运行附加到循环的else块。
  6. 代码:

    import math
    
    def next_prime_palindrome(x):
        while True:
            x += 1
    
            if x > 2 and x % 2 == 0:        # even numbers greater than 2 are non-prime
                continue
    
            s = str(x)                      # compute str(x) just once
            if x > 11 and len(s) % 2 == 0:  # all even-length palindromes are multiples of 11
                x = 10 ** len(s)            # so jump to the next odd-length integer
                continue
    
            if s != s[::-1]:                # palindrome test
                continue
    
            for i in xrange(3, round(math.sqrt(x))+1, 2): # loop over odd potential divisors
                if x % i == 0:              # prime test
                    break
            else: # this else block runs only if no break happened in the loop, so x is prime
                return x
    

    以下是一些测试运行,显示了优化节省大量时间的一些情况:

    >>> next_prime_palindrome(1)
    2
    >>> next_prime_palindrome(3)
    5
    >>> next_prime_palindrome(9)
    11
    >>> next_prime_palindrome(11)
    101
    >>> next_prime_palindrome(99999)
    1003001
    >>> next_prime_palindrome(999999999)
    10000500001
    

    进一步的改进可能是直接产生回文,而不是使用整数开始,并进行回文测试来过滤它们。这会比原来的设计更进一步,所以我会把它留给别人。

答案 2 :(得分:0)

def golf(number):
    primes = []
    i = 2
    while i <= number:
        if isPrime(i, primes):
            primes.append(i)
        i += 1

    answer = primes[-1] + 1
    while True:
        if isPrime(answer, primes):
            primes.append(answer)
        if str(answer) == str(answer)[::-1]:
            return answer
        answer += 1

def isPrime(n, primes):
    for (p for p in primes if p<=n**0.5):
        if n%p == 0:
            return False
    return True

答案 3 :(得分:0)

根据Blckknght的建议进行了改进,谢谢。

def golf(number):
    x = number 
    while True:
        x += 1
        if str(x) != str(x)[::-1]:
            continue
        for i in xrange(2, x):
            if x % i == 0 :
                break
        else:
            return x

答案 4 :(得分:0)

您可以稍微修改您的解决方案,以便创建迭代解决方案:

def golf(number):
    x = number + 1
    while True:     
        is_golf = True
        for i in range(2, x):
            if x % i == 0 or str(x) != str(x)[::-1]:
                is_golf = False
                break

        if is_golf:
            return x
        x += 1