Trie(字典树)是一种用于实现字符串快速检索的多叉树结构。
其实我什么都不知道,直接上模板......
统计出以某个字符串为前缀的单词数量。
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<cstdlib>
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define ll long long
#define ull unsigned long long
#define mem(a,x) memset((a),(x),sizeof ((a)))//x只能是0或-1或false或true
#define debug(x) cout<<"X: "<<(x)<<endl
#define de cout<<"************"<<endl
#define lowbit(x) ((x)&(-x))
#define lson rt<<1
#define rson rt<<1|1
#define gcd(a,b) __gcd(a,b)
#define lcm(a,b) a*b/(__gcd(a,b))
#define inf 0x3f3f3f3f//1e9+6e7
#define eps 1e-8
#define mod 1e9+7
#define N 100010
const double pi=acos(-1.0);
using namespace std;
#define maxn 2000005
int trie[maxn][30];//tree[i][j]表示节点i的第j个儿子的节点编号
bool endd[maxn];//如果结果为真,表示以该节点结尾是一个单词
int tot=1;//结点总数
int sum[maxn];
void init()
{
for(int i=0; i<=tot; i++)
{
endd[i]=false;
for(int j=0; j<30; j++)
trie[i][j]=0;
}
tot=1;
}
void insert_(char *str)
{
int len=strlen(str);
int p=1;
for(int i=0; i<len; i++)
{
int ch=str[i]-'a';
if(trie[p][ch]==0)
trie[p][ch]=++tot;
sum[trie[p][ch]]++;
p=trie[p][ch];
}
endd[p]=true;
}
int find_(char *str)
{
int len=strlen(str);
int p=1;
for(int i=0; i<len; i++)
{
int ch=str[i]-'a';
if(trie[p][ch]==0)
return 0;
p=trie[p][ch];
}
return sum[p];
}
int main()
{
char a[10010];
init();
mem(sum,0);
while(gets(a))
{
if(a[0]=='\0')
break;
insert_(a);
}
ll ans=0;
while(scanf("%s",a)!=EOF)
{
ans=find_(a);
cout<<ans<<endl;
}
return 0;
}
出现的不同单词个数。
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<cstdlib>
#include<sstream>
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define ll long long
#define ull unsigned long long
#define mem(a,x) memset((a),(x),sizeof ((a)))//x只能是0或-1或false或true
#define debug(x) cout<<"X: "<<(x)<<endl
#define de cout<<"************"<<endl
#define lowbit(x) ((x)&(-x))
#define lson rt<<1
#define rson rt<<1|1
#define gcd(a,b) __gcd(a,b)
#define lcm(a,b) a*b/(__gcd(a,b))
#define inf 0x3f3f3f3f//1e9+6e7
#define eps 1e-8
#define mod 1e9+7
#define N 100010
const double pi=acos(-1.0);
using namespace std;
#define maxn 2000005
int trie[maxn][30];//tree[i][j]表示节点i的第j个儿子的节点编号
bool endd[maxn];//如果结果为真,表示以该节点结尾是一个单词
int tot=1;//结点总数
int sum[maxn];
void init()
{
for(int i=0; i<=tot; i++)
{
endd[i]=false;
for(int j=0; j<30; j++)
trie[i][j]=0;
}
tot=1;
}
void insert_(string str)
{
int len=str.length();
int p=1;
for(int i=0; i<len; i++)
{
int ch=str[i]-'a';
if(trie[p][ch]==0)
trie[p][ch]=++tot;
sum[trie[p][ch]]++;
p=trie[p][ch];
}
endd[p]=true;
}
bool find_(string str) //检索字符串是否存在
{
int len=str.length();
int p=1;
for(int i=0; i<len; i++)
{
int ch=str[i]-'a';
if(trie[p][ch]==0)
return false;
p=trie[p][ch];
}
return endd[p];
}
string ss,s;
int main()
{
char a[10010];
init();
mem(sum,0);
while(gets(a))
{
init();
if(strcmp(a,"#")==0)
break;
int ans=0;
stringstream ss(a);
while(ss>>s)
{
if(find_(s))
continue;
else
{
ans++;
insert_(s);
}
}
cout<<ans<<endl;
}
return 0;
}
1402

被折叠的 条评论
为什么被折叠?



