字符串匹配的sunday算法


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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM