1. 程式人生 > >字符串匹配之Sunday算法

字符串匹配之Sunday算法

detail pat 相等 asc kmp算法 http sin not 參考

Sunday算法不像KMP算法那麽復雜,但是效率又比較高,在KMP之上,下面簡單介紹Sunday算法及其實現。

Sunday 算法由 Daniel M.Sunday 在 1990 年提出,它的思想跟 BM 算法很相似:

只不過 Sunday 算法是從前往後匹配,在匹配失敗時關註的是文本串中參加匹配的最末位字符的下一位字符。


如果該字符沒有在模式串中出現則直接跳過,即移動位數 = 匹配串長度 + 1;
否則,其移動位數 = 模式串中最右端的該字符到末尾的距離 +1,使得下一位字符與模式串中與其相等的字符對齊。


下面舉個例子說明下 Sunday 算法。假定現在要在文本串"substring searching algorithm"中查找模式串"search"。

1.剛開始時,把模式串與文本串左邊對齊:

技術分享

2.結果發現在第 2 個字符處發現不匹配,不匹配時關註文本串中參加匹配的最末位字符的下一位字符,即標粗的字符 i,因為模式串 search 中並不存在 i,
所以模式串直接跳過一大片,向右移動位數 = 匹配串長度 + 1 = 6 + 1 = 7,從 i 之後的那個字符(即字符 n)開始下一步的匹配,如下圖:

技術分享

3.結果第一個字符就不匹配,再看文本串中參加匹配的最末位字符的下一位字符,是‘r‘,它出現在模式串中的倒數第3位,於是把模式串向右移動 3 位(r 到模式串末尾的距離 + 1 = 2 + 1 =3),使兩個‘r‘對齊,如下:

技術分享

4.匹配成功。

下面是Sunday算法的javascript實現

function sunday(source, pattern) {
    var sLen = source.length,
        pLen = pattern.length;
    var sIndex = 0,
        pIndex = 0,
        loc = 0;
    while (sIndex < sLen && pIndex < pLen) {
        //索引相等,向後繼續比對
        if (source[sIndex] == pattern[pIndex]) {
            sIndex
++; pIndex++; } else { //not equal,jump var aimChar = source[sIndex + pLen], pAim = pLen - 1; //找索引,與參與匹配的串的下一位的值相等的字符在模式串中的索引 while (pAim > 0) { if (aimChar == pattern[pAim]) { break; } pAim--; } //jump,pLen - pAim就是sIndex應該前進的值,sIndex從0算起 sIndex += pLen - pAim; //record location loc = sIndex; //reset to zero pIndex = 0; } } if (pIndex < pLen) { return -1; } return loc; }

由於Sunday算法每一步的移動量都比較大,因此效率很高。

參考:http://wiki.jikexueyuan.com/project/kmp-algorithm/sunday.html

   http://blog.csdn.net/silver_sail/article/details/8137782

字符串匹配之Sunday算法