kmp模板

字符串查重,先定義2個字符串str1,str2。str1爲被比較的長串,str2爲短串。先通過str2對自身的比較得出一組數字下標,記錄在next數組裏(具體操作下文說明)。然後再進行str1,與str2的比較,這樣在進行比較時長串的遊標就不會回溯,只往下移。詳情請看下文。

首先是str2的自我比較得next數組:

 

如圖i爲前串游標,j爲後串游標,錯開一個表示前後,然後逐個比較。如果後串是首位(即j=0)當前i位所指next[i]=1,如果當前相同則i++;j++;如果之前部分對應一致,則當前next[i]=j;具體代碼如下:

<span style="white-space:pre">	</span>l2=strlen(str2);
        i=1;j=0;next[1]=0;
        while(i<=l2)
        {
            if(j==0||str2[i-1]==str2[j-1])
            {
                i++;
                j++;
                next[i]=j;
            }
            else{
                j=next[j];
            }
        }
然後在比較str2與str1:

如果遇到

直接通過next數組將str2串跳到j=2的位置,在進行比較。如果是普通算法會直接變成i=4的爲,同時j回到第1位,再開始比較。而kmp不需要i遊標的回溯,這樣在處理長串時,效率無疑提高不少。具體代碼如下:

        l1=strlen(str1);
        i=0;j=0;
        while(i<=l1&&j<=l2)
        {
            if(j==0||str1[i-1]==str2[j-1])
            {
                i++;
                j++;
            }
            else j=next[j];
        }
最後判斷j的大小如果j>l2則說明str1中存在串2;

例題SDUTOJ 2772http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2772

題目描述

給定兩個字符串string1和string2,判斷string2是否爲string1的子串。

輸入

 輸入包含多組數據,每組測試數據包含兩行,第一行代表string1(長度小於1000000),第二行代表string2(長度小於1000000),string1和string2中保證不出現空格。

輸出

 對於每組輸入數據,若string2是string1的子串,則輸出string2在string1中的位置,若不是,輸出-1。

示例輸入

abc
a
123456
45
abc
ddd

示例輸出

1
4
-1


代碼如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
    int i,j,l1,l2,next[1000000];
    char str1[1000001],str2[1000001];
    while(~scanf("%s%s",str1,str2))
    {
        l2=strlen(str2);
        i=1;j=0;next[1]=0;
        while(i<=l2)
        {
            if(j==0||str2[i-1]==str2[j-1])
            {
                i++;
                j++;
                next[i]=j;
            }
            else{
                j=next[j];
            }
        }
        l1=strlen(str1);
        i=0;j=0;
        while(i<=l1&&j<=l2)
        {
            if(j==0||str1[i-1]==str2[j-1])
            {
                i++;
                j++;
            }
            else j=next[j];
        }
        if(j>l2)printf("%d\n",i-j+1);
        else printf("-1\n");
    }
    return 0;
}








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章