今天给大家分享的是关于字符串中字典树的内容,这个内容可以帮助我们更好地理解有关字符串的相关知识,将字符串变为数组存在里面,方便统计字符串的内容。主要用于解决多个母字符串,然后询问字串是否存在的问题。



希望大家可以好好地阅读这部分内容,这是关于字典树的模版内容,相信可以帮助大家更好地理解。
题目描述:
小 Z 同学非常喜欢找事,现在有很多名为"事"的字符串,现在小 Z 想要找"事",请你帮助他判断,他今天是否找了两件相同的事。
输入描述
输入第一行包含一个整数 n,表示小 Z 今天找了多少事。
接下来 n 行分别表示 n 件事。
事的输入量不超过 103 ,每个"事"字符串的长度不超过 1000,且所有字母均为小写。
输出描述
若有相同的事输出1,否则输出0。
输入案例:
12
acd
acd
asdfsdf
asd
f
saf
asdf
sfasdfs
f
asdf
asf
asdfs
输出案例:
1
代码部分:
cpp
#include <bits/stdc++.h>
using namespace std;
int nex[1004][26];
int cnt[1004];
int nx=2;
void insert(char a[]){
int x=1;
for(int i=0;a[i];i++){
if(!nex[x][a[i]-'a'])nex[x][a[i]-'a']=nx++;
x=nex[x][a[i]-'a'];
}
cnt[x]++;
}
bool find(char a[]){
int x=1;
for(int i=0;a[i];i++){
x=nex[x][a[i]-'a'];
}
return cnt[x]>1;
}
int main()
{
int n;cin>>n;
for(int i=0;i<n;i++){
char a[1004];
cin>>a;
insert(a);
if(find(a)){
cout<<1<<endl;
return 0;
}
}
cout<<0<<endl;
return 0;
}
⚠️⚠️注意数组的范围
问题二:
问题描述
小蓝是图书馆的管理员,他负责管理图书馆的所有书籍。图书馆有 N 本书,每本书都有名字,分别为 S1,S2,...,SN。
图书馆的读者们经常来询问小蓝,他们会给小蓝一个字符串 T,希望小蓝能告诉他们,图书馆里有多少本书的名字是以 T的前缀开头的。小蓝需要回答他们 M 次这样的询问。
现在,小蓝需要你的帮助。你能帮助小蓝解决这个问题,从而提升图书馆的服务质量吗?
输入格式
第一行输入两个整数 N 和 M(1≤N,M≤104)。
接下来 N 行,每行输入一个字符串Si,表示图书馆中的一本书的名字。
接下来 M 行,每行一个字符串 T,表示读者的询问。
输入字符串的总长度不超过 2×105,且仅包含小写字母。
输出格式
对于每个询问,输出一个整数,表示图书馆中以字符串 T 开头的书的数量。
每个答案占一行。
输入案例:
cpp
5 2
ababc
ababd
aba
ab
a
abab
ccc
输出案例:
cpp
2
0
代码部分:
cpp
#include <bits/stdc++.h>
const int N=1e5+3;
using namespace std;
int nex[N][26];int nx=2;int cnt[N];
void insert(char a[]){
int x=1;
for(int i=0;a[i];i++){
if(!nex[x][a[i]-'a'])nex[x][a[i]-'a']=nx++;
x=nex[x][a[i]-'a'];cnt[x]++;
}
}
int check(char a[]){
int x=1,res=0;
for(int i=0;a[i];i++){
x=nex[x][a[i]-'a'];
res=cnt[x];
}
return cnt[x];
}
int main()
{
int m,n;cin>>m>>n;
for(int i=0;i<m;i++){
char a[N];
cin>>a;
insert(a);
}
for(int i=0;i<n;i++){
char b[N];
cin>>b;
cout<<check(b)<<endl;
}
return 0;
}
这道题也是关于字典树的经典问题,可以拿这道题作为模版问题进行记忆。
第三题:
问题描述
依依是一个住在海边小镇的女孩,她的朋友们分散在世界的各个角落。他们有一个特殊的传递信息的方式,那就是通过海洋传递瓶中信。每个瓶中信里,都装着一串由小写英文字母组成的信息,代表一个友情的密码。
这个夏天,依依在海滩上捡到了 N 个瓶中信,每个瓶中信里都有一条由小写英文字符组成的信息,这些信息分别来自她的 N个朋友。我们记第 i 个朋友的信息为 Si,其中 i=1,2,...,N。
为了找出与自己最有缘分的朋友,依依决定比较这些信息的相似度。这里的"相似度"指的是两条信息从头开始,最长能够匹配的字符数量。
注意,依依并不想比较一条信息与它自身的相似度。
现在,依依希望你能帮助她找出对于每条信息 Si,哪条信息与其最相似,即从开头开始,最长能连续匹配的字符的数量是多少。
输入格式
输入的第一行包含一个整数 N(1≤N≤104)。
接下来的 NN 行,每行包含一个由小写字符构成的字符串 Si,表示小蓝的一个朋友在信封里刻写的信息。保证i=1∑N∣Si∣≤105。
输出格式
输出共 N 行,对于每条信息 Si,输出一个整数,表示与 Si 最接近的信息的最长公共前缀的长度。
输入案例:
cpp
3
abc
ab
bc
输出案例:
cpp
2
2
0
代码部分:
cpp
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+12;
string a[10005];int nex[N][27],cnt[N],nx=2;
void insert(string s)
{int x=1;int n=s.size();
for(int i=0;i<n;i++)
{
if(!nex[x][s[i]-'a'])nex[x][s[i]-'a']=nx++;
x=nex[x][s[i]-'a'];cnt[x]++;
}}
int check(string s)
{int x=1,res=0;int n=s.size();
for(int i=0;i<n;i++)
{
x=nex[x][s[i]-'a'];
if(cnt[x]>1)res=i+1;
}return res;}
int main()
{int n;cin>>n;
for(int i=1;i<=n;i++){cin>>a[i];insert(a[i]);}//加入树上
for(int i=1;i<=n;i++)cout<<check(a[i])<<endl;
return 0;
}
这道题也是关于字典树的问题,明天我将介绍一种更加常用的字符串模型--01🌲
好了,今天的分享就到这里,希望大家多多关注,我们后续再见👋