缩步查找法——一种新的查找算法

先瞎叨叨几句:  

  不知道该给这种算法起个啥名字,暂且就叫它缩步查找法吧,毕竟用到了缩短步长的思想。这是一个懒惰的产物,因为懒得写二分(其实是因为自己的二分老写错),然后就阴差阳错的想出了这种瞎胡搞的算法。后来在一些比赛中还用到过几次,效果不错,所以就想把这个算法具体给分析一遍,就是因为这算法,我还被实验室的人全黑了一遍,他们都说这是个逗比算法...

 


 

进入正题:

  查找最基本的有两种,暴力和二分,在这里不谈二分,就说暴力,暴力的思想就是挨个查找看是否符合条件,而暴力是很容易超时的..QAQ。

  缩步就是在暴力的基础上的改进,摒弃了暴力挨个查找的冗长步骤,而是通过缩短步长来跳跃式查找,比如说你要从0开始查找,找11112,你可以这样查找:

    * 初始位置x为0,初始步长step为10000,然后 x + step = 10000 < 11112 ,没找到;

    * 然后继续 x + step = 20000 > 11112,超过了,然后往回退一步,x = 10000 , 这时候把步长step缩短为原来的十分之一,step = 1000;

    * 继续x + step = 11000 < 11112 , 继续 x + step = 12000 > 11112,又超过了,继续往回退一步 , x = 11000 , 继续缩步 step = 100;

    * 继续x + step = 11100 < 11112 , 继续 x + step = 11200 > 11112 ,同上 x = 11100 , step = 10;

    * 继续x + step = 11110 < 11112 , 继续 x + step = 11120 > 11112 ,同上 x = 11110 ,step = 1;

    * 最后x + step = 11111 < 11112 , 继续 x + step == 11112 , 就这样找到了。

  

  我一般用这个方法来求解方程组的根、找函数零点一类的,因为这个方法特别容易做一些浮点数的题,并且精度什么的也很好控制,还有一点就是由于这个算法是建立在枚举的思想上面,所以有一点就是不用考虑函数什么的是否递增,所以用这种方法做题还是挺快的。但是一些数组中查找某值的问题还是建议用二分,毕竟这种缩步法只是用来偷懒的,小打小闹而已。

  其实这个算法的思想特别简单,原谅了我啰嗦了那么长,大神不要骂我,我只是一个刚接触ACM不久的菜鸟。

  下面用代码来实现上面的算法(ps: 具体题目是求函数f(x)的零点 , f(0) < 0):

x = 0;                                //x的初始查找位置,自己定
step = 1000000;                       //初始步长,自己定
while(step >= 0.0000001) {            //这一步是用来控制精度,自己定
    while(f(x + step) < 0.00)         //函数f(x), 用 x+step 的话就不用返回到上一步了    
        x += step;                    //循环    
            step /= 10;               //缩短步长    
}
printf("%.4lf\n", x);                 //最后得到的x即是所得解

 

缩步查找法与二分查找法的时间复杂度比较:

  如果查找区间长度为N的话,二分是 log2N,这种逗比算法的时间是 5log10N,(因为从1查找到9,平均查找长度是区间长度的一半,所以这个地方就是5) ,算出来查找时间是二分的1.66倍,比二分要稍慢一点,不过比二分好实现一点,ahaha~ 

还有一些关于用到这个算法的题目,等晚点再往上放。

  

  

  

posted on 2014-11-16 20:44  Vking不说话  阅读(608)  评论(3编辑  收藏  举报

导航