python--翻译一段Java程序:已知素数的积,求这2个素数
昨天群里有人贴了下面这张图片,勾起了大家兴趣,引发了大家的讨论。
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。虽然明白求素数的原理,但还没想明白程序如何写时,有人贴了如下这段代码。
因为最近在学 python ,且对其中2个循环的边界上限为什么这样写没想明白,于是把这个程序翻译成 python 版。
下面是我的程序:
def panduan(n): strn = str(n) if not (strn[-1] == '1' or strn[-1] == '7'): # 注1 return False for m in range(2, int(n / 2)): # 注2 if (n % m == 0): return False return True m = m2 = False i = 707829217 for n in range(3, int(i ** 0.5)): # 注3 if (i % n == 0): m = panduan(n) m2 = panduan(int(i / n)) if (m & m2): break print(n, int(i / n), sep = '\t')
解析:1)java中“ for(i = 1; i < 10; i++) ”这样的循环,python中通过“ for i in range(10) ”来变相的实现。
但java中,边界上限可以是浮点数等非整数;而range函数中,参数必须是整数。
所以,2个循环中,向range函数传值时,使用int函数将计算值强制转换为整数。
2)注2,一开始并不明白,为什么要“n/2”,而不直接使用n。
现在认为,这是为了效率优化。因为m作为n的除数,如果n不是质数,那么在“n/2”范围内一定能找到可以整除n的数。
3)注2,原文中,这里的边界上限使用的是“i/3”,这也是一开始让我感到困惑的地方,同样不明白为什么不使用i,并且i的1/3又是如何得来的?
现在看来,也是效率优化。因为题目中很明确的提示了两个乘数有大小,所以这2个数肯定不会大于i的1/2。
至于进一步取到1/3,可能就定的比较随意了,至少原作者认为较小数在1/3内一定出现。或许有更明确的原因,但我还没想明白。
想明白这一点后,既然i是乘积,那么在i的开方中,一定能找到这个较小数。
所以我把上限改为了i的开方。点击这里,可以看python中开方的3种写法。
4)注1,原文中没有这个判断。分析数值“707829217”,因为个位数为7,所以2个乘数的个位数一定是7和1。
因此为了提升效率,增加了一个传入值n的个位数是否为1或7的判断,如果不是直接结束本次函数调用。
需要注意的是,python中“i/n”是一个浮点数。
所以开始增加注1的判断后,因为得到的2个数是非质数,追查发现因为传入值n是浮点数,所以导致该判断未实现预期效果。
解决方法,在传入函数前,先将“i/n”强制转换成整数。
在最后的输出中,给“i/n”增加int转化,也是因为不转换的话,输出是浮点数。
