sunday算法核心思想:啟發式移動搜索步長!
SUNDAY 算法描述:
字符串查找算法中,最著名的兩個是KMP算法(Knuth-Morris-Pratt)和BM算法(Boyer-Moore)。這里介紹一種比BM算法更快一些的sunday查找算法。
例如我們要在"substring searching algorithm"查找"search",剛開始時,把子串與文本左邊對齊:
substring searching algorithm
search
^
結果在第二個字符處發現不匹配,於是要把子串往后移動。但是該移動多少呢?這就是各種算法各顯神通的地方了,最簡單的做法是移動一個字符位 置;KMP是利用已經匹配部分的信息來移動;BM算法是做反向比較,並根據已經匹配的部分來確定移動量。這里要介紹的方法是看緊跟在當前子串之后的那個字 符(上圖中的 'i')。
顯然,不管移動多少,這個字符是肯定要參加下一步的比較的,也就是說,如果下一步匹配到了,這個字符必須在子串內。所以,可以移動子串,使子串中的 最右邊的這個字符與它對齊。現在子串'search'中並不存在'i',則說明可以直接跳過一大片,從'i'之后的那個字符開始作下一步的比較,如下圖:
substring searching algorithm
search
^
比較的結果,第一個字符就不匹配,再看子串后面的那個字符,是'r',它在子串中出現在倒數第三位,於是把子串向前移動三位,使兩個'r'對齊,如下:
substring searching algorithm
search
^
哈!這次匹配成功了!回顧整個過程,我們只移動了兩次子串就找到了匹配位置,是不是很神啊?!可以證明,用這個算法,每一步的移動量都比BM算法要大,所以肯定比BM算法更快。
因此,對於leetcode上的解題:
https://leetcode.com/problems/implement-strstr/
Implement strStr(). Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
完整的Python代碼如下:
class Solution(object): def strStr(self, haystack, needle): """ :type haystack: str :type needle: str :rtype: int REFER: http://blog.csdn.net/kankan231/article/details/22406823 """ char_pos = dict() for i, ch in enumerate(needle): char_pos[ch] = i i = 0 len1 = len(haystack) len2 = len(needle) while i <= len1 - len2: found = True for j, ch in enumerate(needle): if haystack[i+j] != ch: found = False if (i+len2) < len1: if haystack[i+len2] not in char_pos: i += (len2+1) else: i += (len2-char_pos[haystack[i+len2]]) else: return -1 break if found: return i return -1
參考:http://blog.csdn.net/kankan231/article/details/22406823
