zoukankan      html  css  js  c++  java
  • 由100盏灯想到的(二)

     本系列的第一篇:

    http://www.cnblogs.com/dhf327/p/4773672.html

    100盏灯的问题,上次我们算是基本解决了,不管算法上是否够优化,至少我们已经在可接受的时间得到了答案。

    但是最后还留了一道题,亲们,你们是不是已经想出来了?

    一,上次的题目

    上一篇给出了python求一个正整数的所有的因数的方法,这个方法目前工作正常,求单个正整数的所有因数速度上也没有任何问题。

    但是结合上一篇最后的题目,有心的同学一下子就看出问题来了,1到10的12次方,假设求每个数的所有因数需要1毫秒,整个循环总共需要多长时间?(考虑到后期的数字比较大,前期的数字比较小,这个1毫秒还是比较乐观的时间)

     python可以快速计算一下:

    1 print(1000000000000/1000/60/60/24/365)

    结果是 >31.7  这个数的单位应该是吧,我的老天,不是在逗我玩吧。这个时间任谁也接受不了,这个QQ群咱们不加了?

    显然,就算我们使用并行算法,在可接受的时间内,仍不能得到正确的结果。也许可以用集群来处理,又好像大炮打蚊子了。

    此时需要算法优化了。

    二,再谈算法优化

    当常现方式不能解决的时候,我们需要一种新的思路来解决这个问题,因为这基本是个纯数学问题,而我的数字功底一般,那就请出万能的搜索引擎吧,找到两个相关的定理可以用到。

    约数个数定理,约数和定理。这里的约数也就是因数。百度百科的解释如下:

    对于一个大于1正整数n可以分解质因数:n=p1^a1*p2^a2*p3^a3*…*pk^ak,
    则由约数个数定理可知n的正约数有(a₁+1)(a₂+1)(a₃+1)…(ak+1)个,
    那么n的(a₁+1)(a₂+1)(a₃+1)…(ak+1)个正约数的和为
    f(n)=(p1^0+p1^1+p1^2+…p1^a1)*(p2^0+p2^1+p2^2+…p2^a2)*…*(pk^0+pk^1+pk^2+…pk^ak)

    如10=2^1*5^1;  则10的因数个数为 (1+1)*(1+1)=4个,因数和为(2^0+2^1)+(5^0+5^1)=18

    上面定理的内容没有提到,一般的p1<p2<p3...

    证明可以自己去找资料,总之这个内容我们是可以拿来用了。

    如果用这个定理,似乎可以解决我们的问题了,让我们试试看。

    三,分解质因数

    每个数要分解质因数,也就是质数的因数,忘记质数定义的同学请自行百度,

    假设我们有从2开始的连续的质数有序序列,我们可以很快的计算出一个数分解质数的结果。

    m=[2,3,5,7,11,13,17,19,...]

    假设对n进行分解质因数,那么就是从2开始,如果能整除,就用整除后的值再除以2,如果除不尽的时候,就除以下一个值3,依次类推,直到分解完毕。

    这就是有名的短路算法。

    让我们来比较一下,上一篇中我们求所有的因数的算法,可以真正求出一个正整数的所有的因数,而现在利用这个公式,我们可以不用求出所有的因数,就能直接对所有的因数进行求和,似乎是更快了一些。

    实际上,上一篇中的算法不依赖任何其他的东西,只是计算量比较而已,虽然只是从2到n的平方根,但这其中的每个数都要参与运算,计算量很大。

    此时新的短路算法,看起来比较快,但是还有很重要的一点,他需要一个质数的序列!

    问题似乎变复杂了。

    未完待续)

  • 相关阅读:
    excel 读取
    MSDN异步编程概述 [C#] zzhttp://www.cnblogs.com/hxhbluestar/articles/60023.html
    window.opener showModelessDialog showModalDialog 获取|控制父窗体的区别
    MySql中文乱码解决方法
    关于随机数
    javascript 日期处理(注意事项)
    一个简单访问office程序的控件,不依赖officedll
    关于12306的bug
    回车提交
    js动态添加外部js(顶)
  • 原文地址:https://www.cnblogs.com/dhf327/p/4779115.html
Copyright © 2011-2022 走看看