不容小视的算法
自從看了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 stubint[] 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
總結
- 上一篇: Android中进程与线程
- 下一篇: iOS-----简易地CocoaAsyn