python求素数积_python--翻译一段Java程序:已知素数的积,求这2个素数

昨天群里有人贴了下面这张图片,勾起了大家兴趣,引发了大家的讨论。

1659380-20190412153839989-73150754.png

虽然明白求素数的原理,但还没想明白程序如何写时,有人贴了如下这段代码。

04d6a657ada4037c6cac2d3abaf76182948.png

因为最近在学 python ,且对其中2个循环的边界上限为什么这样写没想明白,于是把这个程序翻译成 python 版。

下面是我的程序:

importtime

start=time.clock()defpanduan(n):#strn = str(n)

#if strn[-1] not in ('1', '7', '3', '9'): # 注1

#return False

for m in range(2, int(n / 2)): #注2

if (n % m ==0):returnFalsereturnTrue

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)) #注4

if (m &m2):break

#print(n, int(i / n), sep = '\t')

print('微信号:NY' + str(int(i/n))+str(n))

end=time.clock()print('耗时:{}'.format(end - start))

解析: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)注3,原文中,这里的边界上限使用的是“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、或3和9(感谢 @メ﹎僋翫 指出原代码中的一个疏漏)。

因此为了提升效率,增加了一个传入值n的个位数是否为1或7、3、9的判断,如果不是直接结束本次函数调用。

(因为 注4 的修改,导致 注1 的修改提升的效率不大,新版本中注释掉了这段代码。)

需要注意的是,python中“i/n”是一个浮点数(即使 i 可以被 n 整除)。

所以开始增加注1的判断后,因为得到的2个数是非质数,追查发现因为传入值n是浮点数,所以导致该判断未实现预期效果。

解决方法,在传入函数前,先将“i/n”强制转换成整数。

同样道理,在最后的输出2个质素时,给“i/n”增加int转化,也是因为不转换的话,输出是浮点数。

5)注4,原文中该行代码不在 if语句 中,相当于每次for循环都要执行。

但只有在“i/n”是整数的情况下,判断该数是否素数才有有意义,所以放入 if语句(即 i 能被 n 整除时) 中更合适。

6)因为好奇,注1的优化增加后,虽然能感到和原程序比,效率上提高了很多,但是不知道提高了多少,所以对程序又做了改造。

通过 time.clock() 在程序开始和结束时各获取一次时间,然后对2者求差,已得到每次的程序运行时间。

几种求程序运行时间的方法,请参考这里。

a)按原文翻译后,程序耗时 28.7040 秒左右;

b)在此基础上,增加 注1 的判断,耗时缩短为 12.7571 秒左右;

c)这时,做 注4 的修改,并暂时注释掉 注1,奇迹发生了!耗时在 0.0133秒 左右波动(大多落在 0.013~0.016 范围内);

在 注1 被注释的情况下,这里传参数值时,不转换成 int 型也可以,但观察耗时平均会多 0.001 秒。

原因不是很理解,可能和 int 、float型 的存储机制有关。

d)那么,这时 注1 还能提升效率吗?恢复后,虽然有一次耗时能达到 0.0126秒 ,但多数时间和(c)项比,时间上并没有更优。

所以最终版本,注1 被注释掉了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值