是否有任何关于从给定的int解决下一个更高的素数和回文数的建议。
这是我正在尝试的片段,但它有点慢,如果你有任何我可以测试的好算法,请建议。
#!/usr/bin/python
def next_higher(n):
while True:
s = str(n)
if not any([n % i == 0 \
for i in range(2, int(n**0.5))]) and s == s[::-1]:
return n
n = n + 1
print next_higher(2004)
print next_higher(20)
输出:
10201
101
在素数之前更新了回文的代码测试。比我以前的代码快得多。 我正在实施user2357112的建议。
#!/usr/bin/python
def next_higher(n):
while True:
s = str(n)
if s == s[::-1]:
if not any([n % i == 0 \
for i in range(2, int(n**0.5))]):
return n
n = n + 1
print next_higher(2004111)
print next_higher(2004)
print next_higher(2004)
print next_higher(20)
答案 0 :(得分:5)
你可以做很多优化:
[2] + range(3, int(n**0.5) + 1, 2)
以仅检查2之后的奇数。(此外,您还需要执行sqrt + 1,就像我在评论中提到的那样)()
代替[]
。 []
首先生成完整的因子列表,然后才检查any
。如果您使用()
,它会创建一个生成器,因此只要找到True
值就会停止,而不会计算整个列表。xrange
代替range
(xrange
给出生成器,range
给出一个列表)+ 1
。除了最后两个,这是一个包含大多数优化的版本:
def next_higher(n):
if n % 2 == 0:
n = n - 1
while True:
n = n + 2
s = str(n)
if s == s[::-1]:
if not any((n % i == 0 for i in xrange(3, int(n**0.5) + 1, 2))):
return n
我相信这应该是相当快的。但是如果你愿意的话,你可以进行最后2次优化,使其更快。
答案 1 :(得分:2)
除了已经提出的建议外,
我建议你先得到第一个比给定整数高的回文数。
您可以尝试向外匹配中心数字。
此外,您应该只检查具有奇数位数的数字,因为如果数字具有偶数位数并且它是回文数,那么它将始终被11整除并且不能是素数。
一旦你得到第一个具有奇数位数并且刚好高于当前数字的回文数,请测试它的素数并找到高于此值的下一个回文数。
您可以通过递增中心数字来完成此操作。
继续这样做直到它翻到零。在这种情况下,开始递增两个相邻的数字。
继续,直到你到达一个素数。
答案 2 :(得分:2)
我尝试优化回文检查,即寻找奇怪的回文。 由于第一个数字应该是奇数,我专注于那个部分。 这是下面的代码,假设大于1位数。
def next_odd_palindrome(n):
"""to check the next odd palindrome number"""
if n%2==0:
n=n-1
while True:
n=n+2
s = str(n)
if int(s[0])%2==0:
n = int(str(int(s[0])+1)+ s[1:])
s = str(n)
if s==s[::-1]:
return n
如果有任何错误,请告诉我。
答案 3 :(得分:2)
为了好玩,我实施了Hari Shankar和Abhishek Bansal的所有优化。
它首先发现较高的奇数长度回文,然后以保持其回文性的方式增加回文。然后使用Sieve方法在开头计算的素数检查每个数字。
在我的计算机中,这可以在1秒内处理最多n=10^14
(如果你增加CACHE大小可以更高)= D
primes = []
CACHE = int(10**7) # Cache size for Sieve
# Custom class for immediate printing of output
import sys
class Unbuf:
def __init__(self,stream):
self.stream = stream
def write(self,data):
self.stream.write(data)
self.stream.flush()
sys.stdout = Unbuf(sys.stdout)
def sieve():
global primes
is_prime = [False,False]+([True]*(CACHE-1))
for i in xrange(2,int(CACHE**0.5)):
if is_prime[i]:
is_prime[i*i::i] = [False]*((CACHE-i*i+i)/i)
primes = [num for num, bool_prime in enumerate(is_prime) if bool_prime]
def is_prime(n):
"""Checks whether n is prime"""
global primes
if n<2:
return False
if n==2:
return True
for prime in primes:
if prime>n**0.5+1:
return True
if n%prime==0:
return False
# For the case that the number is bigger than the square of our largest prime
for num in xrange(primes[-1]+2,n**0.5+1,2):
if n%num==0:
return False
return True
def next_higher_odd_length_palindrome(n):
n = str(n)
if len(n)%2==0: # Even length, take the smallest odd length (10(00)*1)
n = '1'+('0'*(len(n)-1))+'1'
else:
middle_idx = len(n)/2
left = int(n[:middle_idx+1])
left_cmp = n[middle_idx::-1]
right_cmp = n[middle_idx:]
# If mirroring left part to right part
# makes the number smaller or equal, then
if right_cmp>=left_cmp:
# Increase the left half number
left = left+1
# Mirror left part to the right part
n = str(left)+str(left)[-2::-1]
return n
def next_higher(n):
if n<=1:
return 2
# Ensure the number is a palindrome of odd length
n = next_higher_odd_length_palindrome(n)
while True:
if is_prime(int(n)):
return int(n)
n = next_higher_odd_length_palindrome(n)
if int(n[0])%2==0:
new_lead = str(int(n[0])+1)
n = new_lead+n[1:-1]+new_lead
import time
print 'Sieving...',
start_time = time.time()
sieve()
print 'Done in %.3fs' % (time.time() - start_time)
print next_higher(2004111)
print next_higher(2004)
print next_higher(20)
while True:
n = int(raw_input('Enter n: '))
start_time = time.time()
result = next_higher(n)
print 'Next higher prime palindrome: %d (calculated in %.3fs)' % (result, time.time() - start_time)
在我的计算机中提供此输出:
Sieving... Done in 1.444s 3007003 10301 101 Enter n: 1999999999 Next higher prime palindrome: 10000500001 (calculated in 0.004s) Enter n: 1999999999999 Next higher prime palindrome: 3000002000003 (calculated in 0.051s) Enter n: 1000000000000 Next higher prime palindrome: 1000008000001 (calculated in 0.030s) Enter n: