字典树模板题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/C_13579/article/details/82189012

字典树模板:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;

const int MAX_S=400005;	//字符串的字符总长度 
int Trie[MAX_S][26],sum[MAX_S],num;
int n,m;
char s[35];

void insert(char s[]);
bool find(char s[],int rt);
int search(char s[]);
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
    {
    	scanf("%s",s);
        insert(s);
    }
    scanf("%d",&m);
    for(int i=1;i<=m;++i)
    {
        scanf("%s",s);
        printf("%d\n",search(s));
    }
}

void insert(char s[])
{
    int u=0,len=strlen(s);
    for(int i=0;i<len;++i)
    {
        int id=s[i]-'a';
        if(!Trie[u][id])	Trie[u][id]=++num;
        ++sum[Trie[u][id]];
        u=Trie[u][id];
    }
}

bool find(char s[],int rt)
{
	bool boo=true;
	int len=strlen(s);
    for(int i=0;i<len;++i)
    {
        int x=s[i]-'a';
        if(Trie[rt][x]==0){//以rt为头结点的x字母不存在,返回0 
			boo=false;	break;
		}
        rt=Trie[rt][x];//为查询下个字母做准备 
    }
    return boo;
    //查询整个单词时,应该return isw[rt] 
}

int search(char s[])
{
    int u=0,len=strlen(s);
    for(int i=0;i<len;++i)
    {
        int x=s[i]-'a';
        if(!Trie[u][x]) return 0;
        u=Trie[u][x];
    }//u经过此循环后变成前缀最后一个字母所在位置的后一个位置 
    return sum[u];//因为前缀后移了一个保存,所以此时的sum[u]就是要求的前缀出现的次数 
}

一,HDU-1251-统计难题  :统计前缀字符串个数

Code :

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

const int MAX_N=400005;
int num;
char ch[15];
int Trie[MAX_N][30],Sum[MAX_N];

void Insert(char ch[]);
int Search(char ch[]);
int main()
{
	while(gets(ch)&&ch[0]!='\0'){
		Insert(ch);
	}
	while(gets(ch)){
		printf("%d\n",Search(ch));
	}
	
	return 0;
}

void Insert(char ch[])
{
	int u=0,len=strlen(ch);
	for(int i=0;i<len;++i)
	{
		int t=ch[i]-'a';
		if(Trie[u][t]==0)	Trie[u][t]=++num;
		u=Trie[u][t];
		++Sum[u];
	}
}

int Search(char ch[])
{
	int u=0,len=strlen(ch),res=0;
	for(int i=0;i<len;++i)
	{
		int t=ch[i]-'a';
		u=Trie[u][t];
		if(!u)	break;
	}
	if(u)	res=Sum[u];
	return res;
}

二,HDU-2072-单词数 :统计不同单词个数

Code :

#include<iostream>
#include<sstream>
#include<cstring>
using namespace std;

const int MAX_N=50005;
int Trie[MAX_N][30],Sum[MAX_N],num;
string str;

void Insert(string s);
int Find();
int main()
{
	ios::sync_with_stdio(false);
	while(getline(cin,str)){
		if(str=="#")	break;
		memset(Trie,0,sizeof(Trie));
		memset(Sum,0,sizeof(Sum));
		num=0;
		stringstream sin(str);
		while(sin>>str){
			Insert(str);
		}
		cout<<Find()<<endl;
	}
	
	return 0;
}

void Insert(string s)
{
	int u=0;
	for(int i=0;i<s.size();++i)
	{
		int t=s[i]-'a';
		if(Trie[u][t]==0)	Trie[u][t]=++num;
		u=Trie[u][t];
	}
	Sum[u]=1;
}

int Find()
{
	int res=0;
	for(int i=0;i<=num;++i)
		res+=Sum[i];
	return res;
}

三,POJ-2001-Shortest Prefixes :求唯一标记前缀字符串,只要找到前缀字符串的个数为1即可

Code:

#include<iostream>
using namespace std;

const int MAX_N=1005;
const int MAX_S=20005;
int Trie[MAX_S][30],Sum[MAX_S],num;
string str[MAX_N];

void Insert(string s);
string Search(string s);
int main()
{
	ios::sync_with_stdio(false);
	int n=0;
	while(cin>>str[n]){
		Insert(str[n++]);
	}
	for(int i=0;i<n;++i)
		cout<<str[i]<<" "<<Search(str[i])<<endl;
	
	return 0;
}

void Insert(string s)
{
	int u=0;
	for(int i=0;i<s.size();++i)
	{
		int t=s[i]-'a';
		if(Trie[u][t]==0)	Trie[u][t]=++num;
		u=Trie[u][t];
		++Sum[u];
	}
}

string Search(string s)
{
	int u=0;
	string st="";
	for(int i=0;i<s.size();++i)
	{
		int t=s[i]-'a';
		u=Trie[u][t];
		st+=s[i];
		if(Sum[u]==1)	break;
	}
	return st;
}

四,POJ-3630-Phone List : 判断是否有字符串是另一字符串的前缀,在构造时对字符串的元素做标记,以及对最后一个字符做特殊标记,在判断即可

Code :

#include<iostream>
#include<cstring>
using namespace std;

const int MAX_S=100005;
int n,num,T;
int Trie[MAX_S][15],Sum[MAX_S];
string str;
bool boo;

bool Insert(string s);
int main()
{
	ios::sync_with_stdio(false);
	cin>>T;
	while(T--){
		memset(Trie,0,sizeof(Trie));
		memset(Sum,0,sizeof(Sum));
		boo=true;	num=0;
		cin>>n;
		for(int i=0;i<n;++i)
		{
			cin>>str;
			if(boo&&!Insert(str))	boo=false;
		}
		if(boo==true)	cout<<"YES"<<endl;
		else	cout<<"NO"<<endl;
	}
	
	return 0;
}

bool Insert(string s)
{
	bool bo=true;
	int u=0;
	for(int i=0;i<s.size();++i)
	{
		int t=s[i]-'0';
		if(Trie[u][t]==0)	Trie[u][t]=++num;
		u=Trie[u][t];
		if(Sum[u]==-1){
			bo=false;	break;
		}
		if(i!=s.size()-1)	Sum[u]=1;
	}
	if(Sum[u])	bo=false;
	Sum[u]=-1;
	
	return bo;
}

猜你喜欢

转载自blog.csdn.net/C_13579/article/details/82189012