KMP

//www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html

//www.acwing.com/solution/content/23907/

先上兩個大佬的博客

能懂基本的思想了

 

 

 

 

 

 第二個圖來自acw的第二個題解

 

 

 

 

 

 看到這裡應該就能明白了

OK了,了解到這裡就能去聽y總的課了…

 

 

 next[i]表示以i為終點的後綴與和從1開始的前綴相等且這個後綴的長度最長,其實也就是之前博客里又說的匹配表

把子串單獨拎出來看

 

 

 

 

 

 

 

 

 然後移動之後就又開始看看下一個點是否匹配了

好了,現在過程都懂了,開始寫代碼:

主要分為兩個部分:

第一個部分:字符串的匹配

 

 

 這個是acw下面的一個評論,本來剛開始還不是很理解,現在很理解了

//KMP的匹配過程
for(int i=1;j=0;i<=m;i++)
{
    while(j&&s[i]!=p[j+1]) j=ne[j];//這是一個往後退的過程,找到一個類似於前綴的另一個與s串匹配的位置 
    if(s[i]==p[j+1]) j++;//如果退無可退之後還不滿足條件,那就到i的下一個位置
    if(j==n)
    {
        //完成匹配 
    }
}

NND,終於懂了…..

刷了三天,知道是個啥意思了,hhh

#include<iostream>
using namespace std;
const int N=100010,M=1000010;
char q[N],s[M];
int ne[N];//保存next數組
int main()
{
    int n,m;
    cin>>n>>q+1>>m>>s+1;//下標均從1開始
    for(int i=2,j=0;i<=n;i++)
    //j表示匹配成功的長度,i表示q數組中的下標,因為q數組的下標是從1開始的,只有1個時,一定為0,所以i從2開始
    {
        while(j&&q[i]!=q[j+1]) j=ne[j];
        //如果不行可以換到next數組
        if(q[i]==q[j+1]) j++;
        //成功了就加1
        ne[i]=j;
        //對應其下標
    }
    //j表示匹配成功的長度,因為剛開始還未開始匹配,所以長度為0
    for(int i=1,j=0;i<=m;i++)
    {
        while(j&&s[i]!=q[j+1]) j=ne[j];
        //如果匹配不成功,則換到j對應的next數組中的值
        if(s[i]==q[j+1]) j++;//到退無可退的時候,就進行下一個i 
        //匹配成功了,那麼j就加1,繼續後面的匹配
        if(j==n)//如果長度等於n了,說明已經完全匹配上去了
        {
            printf("%d ",i-j);
            //因為題目中的下標從0開始,所以i-j不用+1;
            j=ne[j];
            //為了觀察其後續是否還能跟S數組後面的數配對成功
        }
    }

    return 0;
}

代碼還有點小細節懂的不是很徹底,再刷刷吧…

********************************哈哈哈哈,新的一刷又來啦

之前開頭的那個;鏈接僅僅了解一下專有名詞就好,具體代碼的實現和那個還是有一點點差別的

//www.bilibili.com/video/BV1Qb411h7U6/

配上這個動畫,再加上我下面的講解簡直一目了然,我吹的,看個人理解

其實整個KMP的過程,就是一直頻繁移動子串也就是p串的一個過程,可是這個是代碼啊,怎麼可能真的實現移動

但是可以實現指針的移動,也就是剛剛上面所說的退的情況,恕我直言,那個說法對我來說挺不好理解的

現在換一個思路,比如ABCEABDE為s串,ABD為模板串,也就是p串,在C不匹配的時候,直接移動ABD到ABDE的那個位置與之對齊(但實際上就是指針重新恢復到剛開始的那個位置啦)

然後就是移動i的事情啦,因為s[i]==p[j+1]j才會++,如果不滿足條件那就是i++,直到i指針i指針與移動之後的ABD第一個開始匹配(並不是移動的哦,只是指針又指到匹配的那個位置了)

這只是我自己的理解,覺得利於我的理解,一定要配上動畫啊,不然有些乾癟,hhh

其實剛剛所說的就是這個圖

 

Tags: