python-打印回文数字的方块:提高效率
我有任务要做。问题是这样的。你给一个数字,比如说x。程序计算从1开始的数字的平方,并且仅当它是回文时才打印它。程序将继续打印这些数字,直到达到您提供的数字x为止 我已经解决了这个问题。它在正常运行x=10000000时工作正常。在一段合理的时间内执行,工作正常。我想提高代码的效率。如果需要,我愿意更改整个代码。我的目标是制作一个能在大约5分钟内执行10^20的程序python-打印回文数字的方块:提高效率,python,list,palindrome,Python,List,Palindrome,我有任务要做。问题是这样的。你给一个数字,比如说x。程序计算从1开始的数字的平方,并且仅当它是回文时才打印它。程序将继续打印这些数字,直到达到您提供的数字x为止 我已经解决了这个问题。它在正常运行x=10000000时工作正常。在一段合理的时间内执行,工作正常。我想提高代码的效率。如果需要,我愿意更改整个代码。我的目标是制作一个能在大约5分钟内执行10^20的程序 limit = int(input("Enter a number")) def palindrome(limit): count
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)
limit=int(输入(“输入数字”))
def回文(限制):
计数=1
基数=1
计数<限制时:
基数=基数*基数#将数字平方
base=list(str(base))#将数字转换为字符串列表
rbase=base[:]#复制号码
rbase.reverse()#反转此副本
如果len(基本)>1:
i=0
标志=1
当i
这样的东西肯定会执行得更好(避免不必要的额外列表操作),并且更具可读性:
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)
def回文(限制):
基数=1
而基准<极限:
平方=str(基数*基数)
反向=平方[:-1]
如果平方==反向:
打印(平方)
基数+=1
limit=int(输入(“输入一个数字”))
回文(限制)
我想我们可以做得简单一点
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)
def回文(限制):
计数=1
计数<限制时:
基数=计数*计数#将数字平方
base=str(base)#将数字转换为字符串
rbase=base[:-1]#将字符串反转
如果base==rbase:
打印(基本)#如果值匹配则打印
计数+=1
limit=int(输入(“输入一个数字”))
回文(限制)
字符串到数字和数字到字符串的转换是不必要的。字符串可以比较,这就是为什么不应该进行循环 您可以在内存中保留一个不超过某个限制(如L)的方形回文列表。如果输入的数字x小于sqrt(L),您可以简单地迭代回文列表并打印它们。这样您就不必迭代每个数字并检查其方形是否为回文。
你可以在这里找到方形回文列表:他是我的版本:
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
顺便说一句,我的版本给出了更多的结果(0,1,4,9)。好的,这是我的程序。它缓存正方形的有效后缀(即固定的
k
的n^2 mod 10^k
值),然后搜索同时具有该后缀且以后缀反转开始的正方形。这个程序非常快:在24秒内,它列出了10^24以内的所有回文方块
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
样本输出:
0 0
1 1
2 4
3 9
11 121
22 484
26 676
101 10201
111 12321
121 14641
202 40804
212 44944
<snip>
111010010111 12323222344844322232321
111100001111 12343210246864201234321
111283619361 12384043938083934048321
112247658961 12599536942224963599521
128817084669 16593841302620314839561
200000000002 40000000000800000000004
0
1 1
2 4
3 9
11 121
22 484
26 676
101 10201
111 12321
121 14641
202 40804
212 44944
111010010111 12323222344844322232321
111100001111 12343210246864201234321
111283619361 12384043938083934048321
112247658961 12599536942224963599521
128817084669 16593841302620314839561
200000000002 40000000000800000000004
你的程序对我不起作用:TypeError:不能用base=base*base处类型“list”的non int乘以sequence。不,缩进是错误的,的最后四行需要缩进以避免TypeError
。使用4个空格进行缩进,你的代码几乎不可读。要检查一个数字是否是回文,简单地说这就足够了:str(base)==str(base)[::-1]
。如果你想在5分钟内达到10^20,你必须使用一些数学技巧来避免检查每个数字。没有一台你可以访问的计算机可以在五分钟内从1迭代到10^20(即使每次迭代都不做任何事情)。@Shonu93:等等,你是要等到平方等于10^20,还是直到x
等于10^20?因为在第一种情况下,你只需要做10^10的工作,这在5分钟内是可能的。是的,谢谢你的回答。在阅读你的答案之前,我也以类似的方式实现了它。我也有0 1 4 9被输出。我得想办法纠正一下。谢谢!尝试运行一个更大的限制。感谢您的输入!干杯<代码>而循环仍然是不必要的。是的。我只是想让旧的代码保留下来。但是for in
循环更像python。感谢您的输入!干杯