不容小视的算法

自从看了cnblog上那篇讲“野生”程序员的文章,我也时常反思作为科班出身的自己,是不是还带着一些“野生”的做派。我们往往80%的时间在做一些纯业务的事情上,而往往百分之90的时间里面我们的业务量不足够大到需要考虑性能的地步。每天重复地活着,有什么意义呢?

所以常常有人说,算法和数据结构,设计模式,都是并没有什么卵用。我一直对这种观点很反感,计算机编程是 一门科学,科学在于高效。如果我们不考虑大流量、高并发,我们可以很任性地写任何功能,大不了加载缓慢。我们忽略那些看似不重要,或者用不上的黑科技,以为一直呆在地球表面上是最安全的。

我在知乎里面写过一个回复:我见过十年的码畜,也见过一年成架构的神人。之所以有的人用一年走完别人十年走不完的技术道路,是因为关注代码和业务背后的细节,不断积累迭代。最近在看《代码之美》这本书,有些感触。我用一个最不被大家重视的算法为例:

二分法查找。

我对这个算法记忆犹新,大一的时候曹海老师在纸上给我推演了其中过程。我用java代码实现如下:

public class TestBinary {
    /**
     * 二分法查询
     * 
     * @param arr
     * @param value
     * @return
     */
    public static int binary(int[] arr, int value) {
        if (arr.length <= 0) System.out.println("no array to search");
        int low = 0;// 低位
        int high = arr.length -1; //高位
        if (low <= high) {
            int mid = (low + high) /2;
            if (arr[mid] == value) return mid;
            if (arr[mid] > value) {
                high = mid - 1;
            }
            if (arr[mid] > value) {
                low = mid + 1;
            }
        }
        return -1;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] a = {1, 2, 9, 33, 43, 52};
        int value = binary(a, 9);
        System.out.println(value);
    }

}

这是最常规的写法,看上去也没什么问题。但是如果我们要查找的数组变得越来越大,就会出现性能和整型溢出的问题。先说性能吧,其中int mid = (low+high)/2;这句在循环中,不断地在栈上分配临时变量,这也是一种消耗,可以把它写在循环外。溢出问题也是在这句,如果high变量(也就是数组长度)足够大,超过32位机器的2^31 -1的局限,或者64位机的整型极限,那么就会溢出为负数。有人建议写成:

mid = (low + high) >>> 1; 

用位运算来防止整型溢出。对位运算不太熟悉的童鞋可以去看看相关资料。

很多人看到这里就感觉皆大欢喜的happy ending,但是我还不想就这么草率地结束。

这里面就存在一个悖论,java不能造出一个大于最大整型数值长度的数组,那么我该如何检验这个溢出问题呢。而且凭什么说用>>> 1就可以解决。我freephp第一个不服!

如果一直纠结造出数组来验证,那么就走不通了。所以我们换个思路,其实本质就是很大的两个数相加除2或用位运算会不会整型溢出的测试。代码如下:

System.out.println("除以2:"+ ((1000000000+Integer.MAX_VALUE) /2));

System.out.println("除以2:"+ ((1000000000+Integer.MAX_VALUE) >>> 1));

输出结果为:

除以2:-573741824

除以2:1573741823

可见位运算可以保证整型不溢出。

(待续ing)


                   .-' _..`.                  /  .'_.'.'                 | .' (.)`.                 ;'   ,_   `. .--.__________.'    ;  `.;-'|  ./               /|  |               / `..'`-._  _____, ..'     / | |     | |     / /| |     | |    / / | |     | |     /_/  |_|     |_|   \_ |__  |__    |__  |__

原文地址:https://www.cnblogs.com/freephp/p/4969374.html