By 白熊花田(http://blog.csdn.net/whiterbear) 转载需注明出处,谢谢。
(注题目来自:http://www.pythontip.com/)
给你一个正整数列表 L, 如 L=[2,8,3,50], 输出L内所有数字的乘积末尾0的个数,
如样例L的结果为2.(提示:不要直接相乘,数字很多,可能溢出)
由题意可以想出最简单的办法,即将表中所有元素相乘,最后和10取余得到0的个数。提示中说这样会溢出。但是,我测试发现python的长整型居然是无上限的,即可以使用N个数相乘而完全没有出现溢出的情况。好吧,百度后原因是:python运算时当整型数据溢出时会自动转化为长整型,长整型所能处理的范围依赖于(虚拟)内存大小。
对应的程序:
def zeroCount3(): zcount = 0 if 0 in L: print 1 else: res = 1 for i in L: res = res * i while res%10 == 0: zcount += 1 res = res/10 print zcount
或者:
zcount = 0 def zfun(x, y): global zcount res = x*y while res%10 == 0: zcount += 1 res = res/10 return res def zeroCount2(): reduce(zfun, L, 1) print zcount
但是,这样做虽然简单粗暴,但是这样只能适合python,因为其他语言比如C一定会溢出。所以,我们试图分析数据看看能不能找到更好的办法。
我们发现结尾0的个数,取决于最终有多少个10相乘,而10的产生由依赖于有多少个(2,5)对产生。因为一对2和5能够产生一个10。这样,在L中n个数相乘时,我们可以将每个数转化成对应的因数相乘,统计出因数中有多少个2和5对,这样就能直接得出最后0的个数,而不必计算出整个整式值。
比如L=[4,6,32,52,25,79],乘积为=2*2 * 2*3 * 2^5 * 2^2*13 * 5^2 * 79,统计下有2个(2,5)对,这样最后结果中就有2个0。tip:一般因数中2的个数远大于5的出现的个数。
依此给出对应的程序:
def zeroCount1(): if 0 in L: print 1 else: five_count = 0 two_count = 0 for l in L: while l%5 == 0: l = l/5 five_count += 1 while l%2 == 0: l = l/2 two_count += 1 print min(five_count, two_count)
原文地址:http://blog.csdn.net/whiterbear/article/details/45476389