python - 打印回文数字的正方形:提高效率

时间:2013-08-17 18:07:57

标签: python list palindrome

我有一项任务要做。问题是这样的。你给一个数字,比如x。程序计算从1开始的数字的平方,并仅在它是回文时打印它。程序继续打印这些数字,直到达到您提供的数字x。

我已经解决了这个问题。它适用于uptil x = 10000000.在合理的时间内执行正常。我想提高代码的效率。如果需要,我愿意更改整个代码。我的目标是制作一个可以在大约5分钟内执行10 ^ 20的程序。

limit = int(input("Enter a number"))
def palindrome(limit):
 count = 1
 base = 1 
 while count < limit:
  base = base * base #square the number
  base = list(str(base)) #convert the number into a list of strings
  rbase = base[:] #make a copy of the number
  rbase.reverse() #reverse this copy
  if len(base) > 1: 
   i = 0
   flag = 1 
   while i < len(base) and flag == 1:
    if base[i] == rbase[i]: #compare the values at the indices
     flag = 1
    else:
     flag = 0
    i += 1
   if flag == 1:
    print(''.join(base)) #print if values match
 base = ''.join(base)
 base = int(base)
 base = count + 1
 count = count + 1
palindrome(limit)

5 个答案:

答案 0 :(得分:2)

他是我的版本:

import sys

def palindrome(limit):
    for i in range(limit):
        istring = str(i*i)
        if istring == istring[::-1]:
            print(istring,end=" ")
    print()

palindrome(int(sys.argv[1]))

在我的机器上为您的版本计时:

pu@pumbair: ~/Projects/Stackexchange  time python3 palin1.py 100000
121 484 676 10201 12321 14641 40804 44944 69696 94249 698896 1002001 1234321 
4008004 5221225 6948496 100020001 102030201 104060401 121242121 123454321 125686521
400080004 404090404 522808225 617323716 942060249

real    0m0.457s
user    0m0.437s
sys     0m0.012s

和我的:

pu@pumbair: ~/Projects/Stackexchange  time python3 palin2.py 100000
0 1 4 9 
121 484 676 10201 12321 14641 40804 44944 69696 94249 698896 1002001 1234321 
4008004 5221225 6948496 100020001 102030201 104060401 121242121 123454321 125686521
400080004 404090404 522808225 617323716 942060249

real    0m0.122s
user    0m0.104s
sys     0m0.010s

BTW,我的版本提供了更多的结果(0,1,4,9)。

答案 1 :(得分:0)

当然这样的事情会表现得更好(避免不必要的额外列表操作)并且更具可读性:

def palindrome(limit):
  base = 1 
  while base < limit:
    squared = str(base * base)
    reversed = squared[::-1] 
    if squared == reversed:
       print(squared)

    base += 1

limit = int(input("Enter a number: "))
palindrome(limit)

答案 2 :(得分:0)

我认为我们可以做得更轻松一点。

def palindrome(limit):
    count = 1
    while count < limit:
        base = count * count # square the number
        base = str(base) # convert the number into a string
        rbase = base[::-1] # make a reverse of the string
        if base == rbase:
            print(base) #print if values match
        count += 1

limit = int(input("Enter a number: "))
palindrome(limit)

字符串转换为数字和数字转换为字符串转换是不必要的。可以比较字符串,这就是你不应该循环的原因。

答案 3 :(得分:0)

你可以在内存中保留一个方形回文列表达到一定限度(比如说L)。如果输入数字x小于sqrt(L),你可以简单地遍历回文列表并打印它们。这种方式你不必迭代每个数字并检查它的方格是否为回文。

您可以在此处找到方形回文列表:http://www.fengyuan.com/palindrome.html

答案 4 :(得分:0)

好的,这是我的程序。它为正方形缓存有效后缀(即固定n^2 mod 10^k的{​​{1}}的值),然后搜索具有该后缀并以后缀反转开始的正方形。这个程序非常快:在24秒内,它列出了所有的回文正方形,最多可达10 ^ 24。

k

示例输出:

from collections import defaultdict

# algorithm will print palindromic squares x**2 up to x = 10**n.
# efficiency is O(max(10**k, n*10**(n-k)))
n = 16
k = 6

cache = defaultdict(list)

print 0, 0 # special case

# Calculate everything up to 10**k; these will be the prefix/suffix pairs we use later
tail = 10**k
for i in xrange(tail):
    if i % 10 == 0: # can't end with 0 and still be a palindrome
        continue
    sq = i*i
    s = str(sq)
    if s == s[::-1]:
        print i, s
    prefix = int(str(sq % tail).zfill(k)[::-1])
    cache[prefix].append(i)

prefixes = sorted(cache)

# Loop through the rest, but only consider matching prefix/suffix pairs
for l in xrange(k*2+1, n*2+1):
    for p in prefixes:
        low = (p * 10**(l-k))**.5
        high = ((p+1) * 10**(l-k))**.5
        low = int(low / tail) * tail
        high = (int(high / tail) + 1) * tail
        for n in xrange(low, high, tail):
            for suf in cache[p]:
                x = n + suf
                s = str(x*x)
                if s == s[::-1]:
                    print x, s