久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4051|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

KMP算法引入及next推導(dǎo)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:102668 發(fā)表于 2016-1-16 06:57 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
本帖最后由 51hei社區(qū) 于 2016-1-16 06:58 編輯

                        前提條件:
S代表主串,
P代表模式串
下標從0開始

引入:下面兩個字符串,判斷P是否是S的子串
S: a b a b a b c a b c a c b ab
P: a b c
最普通的算法就是拿S和P一個一個比較,如果發(fā)現(xiàn)某一次匹配失敗,則S從第一個P從頭,再次進行比較.直到全部匹配結(jié)束.
缺點:復(fù)雜度最壞O(n*m),同時下標回溯發(fā)生在S和P中.

KMP算法:如果概念很熟悉.請直接跳過~~~
如果某一次匹配失敗,那么回溯多少合適呢?
比如:
S : ababcabc
P: ababcaba
現(xiàn)在最后一個字符匹配失敗.
我們來分析下最簡單的模式匹配過程:S回溯到下標1.P從頭開始,如下
ababcabc
ababcaba
繼續(xù)匹配,第一次即失敗. S回溯到下標2.P從頭開始,如下
ababcabc
ababcaba
繼續(xù)匹配,第三次即失敗. S回溯到下標3.P從頭開始,如下
ababcabc
ababcaba
繼續(xù)匹配,第一次即失敗. S回溯到下標4.P從頭開始,如下
ababcabc
ababcaba
繼續(xù)匹配,第一次即失敗. S回溯到下標5.P從頭開始,如下
ababcabc
ababcaba
繼續(xù)匹配…結(jié)果到了c碰到第二次匹配失敗…
注意第一次c是匹配到P的最后一個字符失敗,第二次是匹配到P的第三個字符失敗.
再這兩次的過程中.做了很多工作..
我們發(fā)現(xiàn)是不是可以再這方面優(yōu)化呢
我們發(fā)現(xiàn)無論S怎么進行回溯,其下標最后判斷總是可以再c這個上面.
還有P回溯時,其實只要直接做
ababcabc
ababcaba
這一次就好了.
接著上面的問題,也就是說回溯多少合適呢?再這里P回溯2比較合適

證明:S0,S1,………………………………Si-1,Si
P0,P1,………………………………Pj-1,Pj
假設(shè)在Si和Pj中發(fā)生的匹配失敗.那我們肯定知道
S0,S1,………………………………Si-1
P0,P1,………………………………Pj-1
是相等的.
假設(shè)我們P回溯到下標k比較合適,也就是說下一次比較是Si和Pk.
那么肯定有
S0,S1,………………………………Si-1,Si
P0,P1,………………………………Pj-1,Pj
P0,P1,…………Pk-1,Pk
P0,P1,…………Pk-1 =Si-k…………Si-1因為S0,…Si-1 和P0,…Pj-1是相等的,且j是大于k的值
所以P0,P1,…………Pk-1 =Pj-k, …………Pj-1
所以看出.S不用回溯.回溯只跟P有關(guān).
我們既然每次都可以回溯一個比較合理的值,那算法就非常好寫了.
關(guān)鍵就是這個k如何去尋找...這個下回再說.


--------------------------------------------------


上回說到.要確保P0,P1,…………Pk-1 = Pj-k, …………Pj-1這個表達式成立
則需要找到里面的k值,next有以下定義:

既然是推導(dǎo),肯定要設(shè)定一些條件.我們假設(shè)
已有next[j] = k ,求next[j+1] = ?
既然已有next[j] = k,那么肯定有.P0,P1,…………Pk-1  =  Pj-k,…………Pj-1,但我們對于Pk 和 Pj的關(guān)系不清楚,讓我們分開討論
如果此時Pk = Pj
那么肯定有 P0,P1,…………Pk-1  =  Pj-k, …………Pj-1,Pj明顯看到左右的長度都加了1.也就是說在原來的基礎(chǔ)上長度加了1.
則 next[j+1] = next[j] + 1 = k + 1;
如果此時Pk ≠ Pj
這地方很繞...最起碼我學(xué)習(xí)的時候是...請詳細看,我也盡量分析的詳細點.
說明不會含有[0,k]長度的字符串與[k+1,j-1]
雖然這個不相等,但有可能比k小的前綴是相等的.但到底Pj 和前面的哪個字符串相等呢?
這是不是又牽扯到一個模式匹配的問題捏?  答案是的.
把模式串的后面部分看作新的主串 Pj-k, …………Pj-1,Pj
模式串前面部分看作新的模式串  P0,P1,…………Pk-1,Pk 去尋找新的匹配k'
這時候的步驟是:
1:出現(xiàn)了Pj和Pk不同.這時候根據(jù)KMP算法,需要回溯P產(chǎn)生k'.其實就是移動next(k).
2:由于帶入后末尾2個匹配就是一樣的了.Pk' = Pj所以就可以得出,從j+1的字符之前存在一個長度為k'的最長字串
   P0……..Pk' = Pj-k’……Pj.也就是說next[j+1] = k’+1
   next[j+1] = next(k) + 1;

舉個例子吧.
0         1        2        3        4        5        6        7        8        9          10
-1
0
0
1
2
0
1
2
3
4
?
a
b
a
b
c
a
b
a
b
a
b
現(xiàn)在求next(10)?
分解成next(9+1) ,已知next(9) = 4 ,判斷P4 == P9?
因為P4=c P9=a 所以不相等next(9+1) = next(4) + 1 = 3  請自己驗證.
下面用白話解釋上面的公式下,看next(9) = 4,那從9往前看4個 是abab....肯定第一個到第四個也是abab
假設(shè)如果next(10) = 5 如果從10往前面看ababa 第一個到第五個肯定也是ababa這個是肯定的.但實際上第一個到第五個是ababc
但p[19] = a ...發(fā)現(xiàn)了吧是拿a和c比的.結(jié)果發(fā)現(xiàn)不同..
說明[0,k]長度的字符串與[k+1,j-1]是不會相同的.只有從[0,k]中找一個k'來進行小范圍的匹配的...這個東西明顯就是next[k]...
希望我說明白了.哈哈

再來一個吧next(6)?
分解成next(5+1) ,已知next(5) = 0 ,判斷P5 == P0?
因為P5=a P0=a 所以相等next(5+1) = next(5) + 1 = 1  請自己驗證.


其實next算法還有能可以優(yōu)化的...因為有一種極端的情況.下回說~

-------------------------------------------


                        還有一種特殊情況需要考慮:
例如:
aaabaaabaaabaaabaaab
aaaab
使用上次我們說的算法計算出next
next[j] = -10123
下面進行匹配過程:
s[3] = b ,p[3] = a 不匹配,P回溯到next[3].發(fā)現(xiàn)還是a,再回溯還是a再回溯....
其實a和a是相同的,我們應(yīng)該有個策略告訴他,不需要再重復(fù)比較了.
于是
本來sj 不等于 pi的   那么要sj和pk相比. 而k=next[ i]的
此時如果pi=pk的話,那么sj肯定也不等于pk,所以就不用比了.
這時候回溯多少可以與next[next[ i]]相同....
修正后
next[j] = –1 -1 -1 -1 3
KMP算法告一段落~有時間把算法貼上來~

附代碼:VC2005編譯成功
#include<string.h>

template<typenameT>
classPatternMatch
{
public:
   virtual~PatternMatch(){}
   
   virtualintmatch(constT* source,intsourcelen,constT* pattern,intpatternlen) = 0;
};

template<typenameT>
classKmp:publicPatternMatch<T>
{
public:
   virtualintmatch(constT* source,intsourcelen,constT* pattern,intpatternlen)
   {
        intres = -1;
        if (!source || sourcelen<=0|| !pattern ||patternlen<=0)
        {
           returnres;
        }
        int* next = newint[patternlen];
        if (!next)
        {
           returnres;
        }

        do
        {
           if (generate_next(pattern,patternlen,next)<0)
           {
               break;
           }
           inti = 0;
           intj = 0;
           while(i<sourcelen&&j<patternlen)
           {
               if(-1==j ||source[i]==pattern[j])
               {
                   ++i;
                   ++j;
               }
               else
               {
                   j = next[j];
               }
           }
           if (j>=patternlen)
           {
               res =i-patternlen;
           }
        }while (false);

        delete []next;
        returnres;
   }
protected:
   intgenerate_next(constT* pattern,intpatternlen,int* nextarray)
   {
        if (!pattern || patternlen<=0|| !nextarray)
        {
           return -1;
        }

        nextarray[0] = -1;

        inti = 0;
        intj = -1;
        while (i<patternlen-1)
        {
           if(-1==j ||pattern[i]==pattern[j])
           {
               ++i;
               ++j;
               if (pattern[i]!=pattern[j])
               {
                   nextarray[i] = j;
               }
               else
               {
                   nextarray[i] = nextarray[j];
               }
           }
           else
           {
               j = nextarray[j];
           }
        }
        return 1;
   }
};

voidmain()
{
   Kmp<char>a;
   intpos = a.match("abcde",5,"cd",2);
}






分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 天堂成人国产精品一区 | 国产一级特黄视频 | 国产一级电影在线观看 | 国产在线高清 | 韩国主播午夜大尺度福利 | 在线一区观看 | 精品视频一区二区三区 | 另类a v| 中文字幕精品一区 | 欧美精品在线免费观看 | 欧美高清视频在线观看 | 国产成人精品综合 | 亚洲精品中文字幕中文字幕 | 在线免费观看a级片 | 99精品视频在线 | 国产一区二区精品在线观看 | 亚洲电影一区二区三区 | 日韩中文一区 | 日韩精品久久久久久 | 亚洲h视频 | 日韩电影一区 | 日日骚网| 国产一区不卡 | 色综合久久天天综合网 | 免费av毛片 | 色综合天天天天做夜夜夜夜做 | 黄色毛片免费看 | 中文字幕不卡 | 91精品欧美久久久久久久 | 精品国产伦一区二区三区观看体验 | 性高朝久久久久久久3小时 av一区二区三区四区 | 欧美精品在欧美一区二区少妇 | 精品欧美视频 | 99精品免费视频 | 亚洲日本一区二区 | 国产精品99久久久久久久久 | 亚洲网站在线观看 | 亚洲性人人天天夜夜摸 | 日韩电影免费在线观看中文字幕 | 亚洲欧美日韩中文在线 | 日本不卡一区二区 |