當初腦袋一熱就把KMP寫出來了,現在期末複習腦子冷靜不下來,大半天沒看懂KMP在說啥。好吧,總算花了一個鐘看懂KMP了,趕緊記下來別以後又想不去來了。
KMP是通過一個next數組來輔助匹配的。
next數組裏面保存的是每個數它是跟在從0開始的哪個子串的後面。
find的時候一旦發生不匹配就調到子串next的位置從而減少查找時間。
詳情可看數據結構課本81頁
自己寫的代碼如下,裏面在找next數組時用了一個技巧,從而可以利用先找好的next來節約時間
#include<iostream>
#include<string>
using namespace std;
class KMP
{
private:
string mainstr;
string substr;
int *next;
int sublen;
int mainlen;
int pos;
public:
KMP(string a,string b)
{
mainstr.assign(a);
substr.assign(b);
sublen=substr.length();
mainlen=mainstr.length();
next=new int[sublen];
pos=0;
getnext();
KMPfind();
}
~KMP()
{
delete [] next;
}
void inputnext()
{
for(int i=0;i<sublen;i++)
{
cout<<next[i]<<" ";
}
cout<<endl;
}
void inputpos()
{
cout<<pos+1<<endl;
}
void getnext()
{
int k,j;
for(int i=0;i<sublen;i++)
{
if(i==0)
{
next[i]=-1;
continue;
}
if(i==1)
{
next[i]=0;
continue;
}
j=i-1;
k=next[j];
while(1)
{
if(k==-1)
{
next[i]=0;
break;
}
if(substr[k]==substr[j])
{
next[i]=k+1;
break;
}
else
{
k=next[k];
}
}
}
}
void KMPfind()
{
int j=0;
int i=0;
while(1)
{
if(j==sublen)
{
break;
}
if(i==mainlen)
{
pos=-1;
break;
}
if(mainstr[i]==substr[j])
{
i++;
j++;
}
else
{
if(j==0)
{
i++;
pos++;
}
else
{
j=next[j];
pos=i-j;
}
}
}
}
};
int main()
{
int t;
cin>>t;
while(t--)
{
string a;
string b;
cin>>a>>b;
KMP obj(a,b);
obj.inputnext();
obj.inputpos();
}
return 0;
}