昨天我們編寫了簡單的字元查詢函式。雖然比較簡單,但是也算能用。然而,經過我們仔細分析研究一下,這麼乙個簡單的函式還是有改進的空間的。在什麼地方改進呢?大家可以慢慢往下看。
下面的**是優化前的**,現在再貼一次,這樣分析起來也方便些:
char* strstr(const char* str, char* data)
if(index == len)
return (char*) str;
str++;
} return null;
}
不知道朋友們發現沒有,原來的while條件中有乙個很費時的操作。那就是每次str移動的時候,都需要判斷str的長度大小。如果str的長度遠大於data的長度,那麼計算str長度的時間是相當可觀的。
int check_length_of_str(const char* str, int len)
return 1;
}char* strstr(const char* str, char* data)
if(index == len)
return (char*) str;
str++;
} return null;
}
上面的**很好地解決了長度判斷的問題,這樣一來每次比較的長度很短,只要判斷len的大小字元長度即可。但是,我們還不是很滿足,如果兩者不比較豈不更好。那麼,有沒有這個可能?我們發現,如果str在每次比較不成功的時候,就會自己遞增一位。那麼我們只要判斷這一位是不是『\0』不就可以了嗎?所以說,我們的**還可以寫成下面的形式。
char* strstr(const char* str, char* data)
if(index == len)
return (char*) str;
if('\0' == str[len])
break;
str++;
} return null;
}
和上面第一次的優化不同,我們在進入while之前會判斷兩者的長度區別,但是經過第一次判斷之後,我們就再也不用判斷了,因為接下來我們只要判第n個元素是否為『\0』即可,原來的n-1個元素我們已經判斷過了,肯定是合法的元素。為什麼呢?大家可以好好想想。
(二)、kmp演算法
kmp演算法本質上說是為了消除查詢中的多餘查詢步驟。怎麼就產生了多餘的查詢步驟了呢。我們可以用示例說話。假設有下面兩個字串:
a: baaaaabcd
b: aaaab
那麼這兩個查詢的時候會發生什麼現象呢?我們可以看一下:
/* 1 2 3 4 5 6 7 8 9
* a: b a a a a a b c d
* b: a a a a b
* 1 2 3 4 5 6 7 8 9
*/
我們發現b和a在從第2個元素開始比較的時候,發現最後乙個元素是不同的,a的第6個元素是a,而b的第5個元素是b。按照普通字串查詢的演算法,那麼下面a會繼續向右移動一位,但是事實上2-5的字元我們都已經比較過了,而且2-5這4個元素正好和b的前4個元素對應。這個時候b應該用最後一位元素和a的第7位元素比較即可。如果這個計算步驟能省下,查詢的速度不就能提高了嗎?
【預告: 下面一篇部落格介紹kmp的編寫和多核查找演算法】
一步一步寫演算法(之查詢)
無論是資料庫,還是普通的erp系統,查詢功能資料處理的乙個基本功能。資料查詢並不複雜,但是如何實現資料又快又好地查詢呢?前人在實踐中積累的一些方法,值得我們好好學些一下。我們假定查詢的資料唯一存在,陣列中沒有重複的資料存在。1 普通的資料查詢 設想有乙個1m的資料,我們如何在裡面找到我們想要的那個資...
一步一步寫演算法(之查詢)
無論是資料庫,還是普通的erp系統,查詢功能資料處理的乙個基本功能。資料查詢並不複雜,但是如何實現資料又快又好地查詢呢?前人在實踐中積累的一些方法,值得我們好好學些一下。我們假定查詢的資料唯一存在,陣列中沒有重複的資料存在。1 普通的資料查詢 設想有乙個1m的資料,我們如何在裡面找到我們想要的那個資...
一步一步寫演算法(之字串查詢 上篇)
字串運算是我們開發軟體的基本功,其中比較常用的功能有字串長度的求解 字串的比較 字串的拷貝 字串的upper等等。另外乙個經常使用但是卻被我們忽視的功能就是字串的查詢。word裡面有字串查詢 notepad裡面有字串查詢 winxp裡面也有系統自帶的字串的查詢,所以編寫屬於自己的字串查詢一方面可以提...