1. 程式人生 > 其它 >ML .NET 貓狗影象分類

ML .NET 貓狗影象分類

首先是 KMP 。

\(a\) 是長度為 \(n\) 的原串, \(b\) 是長度為 \(m\) 匹配串。

暴力:

for(register int i=1;i<=n;i++)//列舉起點
	for(register int j=1;j<=m;j++)
	{
		if(s[i+j-1]!=p[j])break;
		if(j==m)printf("%d\n",i);
	}

\(nxt\) 表示在 \(p\) 中,以 \(p_i\) 結尾的字尾,能夠匹配的從 \(1\) 開始的 \(\color{red}{非平凡}\) 字首的最大長度。

非平凡代表不是原串子集。

加過 \(nxt\)

的程式碼有兩部分。

部分1:求 \(nxt\) 的過程。

首先一定的是 \(nxt_0=nxt_1=0\)

for(register int i=2,j=0;i<=lb;i++)//現在起點是i,匹配到j 
{
	while(j&&b[i]!=b[j+1])j=nxt[j];//如果開始都不等於,那就直接跳
	if(b[i]==b[j+1])j++;//如果匹配成功了,就可以匹配下一位
	nxt[i]=j;//當前最多匹配j位 
}

接下來嘗試像暴力一樣匹配,如果失配,就直接跳到 \(nxt_j\)

for(register int i=1,j=0;i<=la;i++)//起點是i,b匹配到j位 
{
	while(j&&a[i]!=b[j+1])j=nxt[j];//同上,直接跳 
	if(a[i]==b[j+1])j++;//匹配,下一位 
	if(j==lb)//全部匹配到了 
	{
		printf("%d\n",i-lb+1);
		j=nxt[j];//還是得跳 
	}
}

程式碼實現:

#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e6+5;
string a,b;
int la,lb;
int nxt[MAXN];
int main()
{
    cin>>a>>b;
    la=a.size(),lb=b.size();
    a=" "+a,b=" "+b;
    for(register int i=2,j=0;i<=lb;i++)
    {
        while(j&&b[i]!=b[j+1])j=nxt[j];
        if(b[i]==b[j+1])j++;
        nxt[i]=j;
    }
    for(register int i=1,j=0;i<=la;i++)
    {
        while(j&&a[i]!=b[j+1])j=nxt[j];
        if(a[i]==b[j+1])j++;
        if(j==lb)
        {
            printf("%d\n",i-lb+1);
            j=nxt[j];
        }
    }
    for(register int i=1;i<=lb;i++)
        printf("%d ",nxt[i]);
    return 0;
}