KMP:
获得next数组:
void getNext()
{
nxt[0] = -1;
for(int i = 1; i < n; i++)
{
int p = nxt[i-1];
for(; p != -1 && str[p+1] != str[i]; p = nxt[p]);
p = str[p+1] == str[i] ? p+1 : -1;
nxt[i] = p;
}
}
KMP匹配:返回母串上与子串匹配的第一个位置的起始处
int kmp()
{
int i = 0, j = 0;
for(; i < n; )
{
if(str[i] == pat[j])
{
i++;
j++;
if(j == m) return i-m+1;
}
else
{
if(j == 0) i++;
else
{
j = nxt[j-1]+1;
}
}
}
return -1;
}
AC自动机:
class Node
{
public:
int next[30], fail;
int endCnt;
void clear()
{
memset(next, 0, sizeof next);
endCnt = 0;
fail = 0;
}
};
Node node[N];
class Trie
{
public:
int root, cnt;
void init()
{
cnt = 0;
root = newNode();
node[0].clear();
}
int newNode()
{
node[++cnt].clear();
return cnt;
}
void ins(char str[], int len)
{
int p = root;
for(int i = 0; i < len; i++)
{
int cur = str[i]-'A';
if(!node[p].next[cur])
{
node[p].next[cur] = newNode();
}
p = node[p].next[cur];
}
node[p].endCnt++;
}
void build()
{
queue<int> q;
q.push(root);
while(!q.empty())
{
int cur = q.front();
q.pop();
for(int i = 0; i < 26; i++)
{
int nxt = node[cur].next[i];
if(nxt)
{
int p = node[cur].fail;
for(; p != 0 && node[p].next[i] == 0; p = node[p].fail);
p = p == 0 ? root : node[p].next[i];
node[nxt].fail = p;
q.push(nxt);
}
}
}
}
int match(char str[], int len)
{
int p = root, res = 0;
for(int i = 0; i < len; i++)
{
int cur = str[i]-'A';
for(; p && node[p].next[cur] == 0; p = node[p].fail);
p = p ? node[p].next[cur] : root;
int tp = p;
for(; tp && node[tp].endCnt > 0; tp = node[tp].fail)
{
res += node[tp].endCnt;
node[tp].endCnt = 0;
}
}
return res;
}
};