字符串查重,先定義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
題目描述
輸入
輸出
示例輸入
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;
}