转载:https://blog.csdn.net/v_july_v/article/details/7041827
查找相同字符串
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int N=100;
int nxt[100];
void GetNextval(char* p)
{
int pLen = strlen(p);
nxt[0] = -1;
int k = -1;
int j = 0;
while (j < pLen - 1)
{
//p[k]表示前缀,p[j]表示后缀
if (k == -1 || p[j] == p[k])
{
++j;
++k;
//较之前nxt数组求法,改动在下面4行
nxt[j] = k;
}
else
{
k = nxt[k];
}
}
}
int kmp(char* s, char* p)
{
int i = 0;
int j = 0;
int sLen = strlen(s);
int pLen = strlen(p);
GetNextval(p);
while (i < sLen && j < pLen)
{
//①如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++
if (j == -1 || s[i] == p[j])
{
i++;
j++;
}
else
{
//②如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = nxt[j]
//nxt[j]即为j所对应的nxt值
j = nxt[j];
}
}
if (j == pLen)
return i - j;
else
return -1;
}
char a[100],b[100];
int main()
{
while(scanf("%s%s",a,b)!=EOF)
{
if(kmp(a,b)!=-1)
printf("ans= %d\n", kmp(a,b));
else
printf("Not find\n");
}
return 0;
}
strstr(s1,s2)判断s1中有没有s2有则返回字符没有就返回NULL
exkmp
扩展kmp处理的是:对于一个串T TT,串S SS每个后缀和串T TT的最长公共前缀。
int Next[maxn],extend[maxn];
char s[1000050],t[1000050];
void getNext(char* str){
int i=0,j,pos,len=strlen(str);
Next[0]=len;
while(str[i]==str[i+1]&&i+1<len)i++;Next[1]=i;
pos=1;
for(int i=2;i<len;i++){
if(Next[i-pos]+i<Next[pos]+pos){
Next[i]=Next[i-pos];
}
else{
j=Next[pos]+pos-i;
if(j<0)j=0;//如果i比最远的的小,说明得从头开始。
while(i+j<len&&str[j]==str[j+i])j++;Next[i]=j;
pos=i;
}
}
}
void Exkmp(char* s,char* t){
int i=0,j,pos,l1=strlen(s),l2=strlen(t);
getNext(t);
while(s[i]==t[i]&&i<l1&&i<l2)i++;extend[0]=i;
pos=0;
for(int i=1;i<l1;i++){
if(Next[i-pos]+i<extend[pos]+pos)
extend[i]=Next[i-pos];
else{
j=extend[pos]+pos-i;
if(j<0)j=0;
while(i+j<l1&&j<l2&&s[i+j]==t[j])j++;extend[i]=j;
pos=i;
}
}
}