bryce1010专题训练——Trie树

bryce1010模板

1.1 前缀个数查询
hdu1251 http://acm.hdu.edu.cn/showproblem.php?pid=1251
数组写法:

#include 
#include 
using namespace std;

int trie[1000010][26];    //数组形式定义字典树,值存储的是下一个字符的位置
int num[1000010]={0};    //附加值,以某一字符串为前缀的单词的数量
int pos = 1;

void Insert(char word[])    //在字典树中插入某个单词
{
    int i;
    int c = 0;
    for(i=0;word[i];i++){
        int n = word[i]-'a';
        if(trie[c][n]==0)    //如果对应字符还没有值
            trie[c][n] = pos++;
        c = trie[c][n];
        num[c]++;
    }
}
int Find(char word[])    //返回以某个字符串为前缀的单词的数量
{
    int i;
    int c = 0;
    for(i=0;word[i];i++){
        int n = word[i]-'a';
        if(trie[c][n]==0)
            return 0;
        c = trie[c][n];
    }
    return num[c];
}

int main()
{
    char word[11];
    while(gets(word)){
        if(word[0]==NULL)    //空行。gets读入的回车符会自动转换为NULL。
            break;
        Insert(word);
    }
    while(gets(word))
        printf("%d\n",Find(word));
    return 0;
}

1.2 前缀个数查询
POJ2001
https://vjudge.net/problem/POJ-2001

#include
#include
#include
using namespace std;
char a[10001][31];
int tot,size;
int sz,t[300001][26],s[300001];
void insert(char ch[])
{
    int k,len=strlen(ch+1),now=0;
    for(int p=1;p<=len;p++)
    {
    	  k=ch[p]-'a';
    	  if(t[now][k]==0)t[now][k]=++sz;
        now=t[now][k];
        s[now]++;
    }
}
void ask(char ch[])
{
	int now=0,k,len=strlen(ch+1);
	for(int p=1;p<=len;p++)
	{
		if(s[now]==1)break;
		k=ch[p]-'a';
		printf("%c",ch[p]);
		now=t[now][k];
   }
}
int main()
{
    while(scanf("%s",a[++tot]+1)!=EOF)insert(a[tot]);
    for(int i=1;i<=tot;i++)
    {
        printf("%s ",a[i]+1);
        ask(a[i]);
        printf("\n");
    }
    return 0;
}

参考:
https://blog.csdn.net/cyc66/article/details/47047933

你可能感兴趣的:(1.1)