您的位置:首页 > 其它

KMP && AC自动机模板

2015-08-27 23:19 239 查看
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
;
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;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: