kmp&字典树 模板

kmp:

const int maxn=1e5+5;
char s[maxn],p[maxn];
int nex[maxn];
int KmpSearch(char* s, char* p)
{
	int i = 0;
	int j = 0;
	int sLen = strlen(s);
	int pLen = strlen(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 = next[j]    
			//next[j]即为j所对应的next值      
			j = nex[j];
		}
	}
	if (j == pLen)
		return i - j;
	else
		return -1;
}
void GetNext(char* p,int next[])
{
	int pLen = strlen(p);
	nex[0] = -1;
	int k = -1;
	int j = 0;
	while (j < pLen - 1)
	{
		//p[k]表示前缀,p[j]表示后缀
		if (k == -1 || p[j] == p[k]) 
		{
			next[++j] = ++k;
		}
		else 
		{
			k = next[k];
		}
	}
}
//优化过后的next 数组求法
void GetNextval(char* p, int next[])
{
	int pLen = strlen(p);
	next[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;
			//较之前next数组求法,改动在下面4行
			if (p[j] != p[k])
				next[j] = k;   //之前只有这一行
			else
				//因为不能出现p[j] = p[ next[j ]],所以当出现时需要继续递归,k = next[k] = next[next[k]]
				next[j] = next[k];
		}
		else
		{
			k = next[k];
		}
	}
}

  字典树:

const int maxn=1e5+5;
int trie[maxn][26];
int sum[maxn];
int exist[maxn];
char s[maxn];
int tot=0;
void insert(char s[])  //插入字符串;
{
    int len=strlen(s);
    int root=0;
    for(int i=0;i<len;i++)
    {   
        int id=s[i]-'a';
        if(trie[root][id]==0)
        {
            trie[root][id]=++tot; //tot新建节点编号;
            exist[root]=0;
        }
        root=trie[root][id];
        sum[root]++;   //表示有相同该前缀的单词个数;
    }
    exist[root]=1;   //该节点是存入的单词最后一位可以用来查询是否有这个单词;
}
// 查找是否为插入单词
bool find(char s[])
{
    int len=strlen(s);
    int root=0;
    for(int i=0;i<len;i++)
    {
        int id=s[i]-'a';
        if(trie[root][id]==0)  //不存在直接退出;
        {
            return false;
        }
        root=trie[root][id];
    }
    if(exist[root])
    {
        return true;
    }
    else return false;
}
// 查找前缀为 s出现的次数;
int find_sum(char s[])
{
    int len=strlen(s);
    int root=0;
    for(int i=0;i<len;i++)
    {
        int id=s[i]-'a';
        if(trie[root][id]==0)
        {
            return  0;
        }
        root=trie[root][id];
    }
    return sum[root];
}
原文地址:https://www.cnblogs.com/zpj61/p/13435925.html