2025.7.3 字典树1
2025.7.3 字典树(Trie)
为啥做这个题单?而且没做完
字典树的应用
查找已出现过的字符串
实现
构造
void add(string s){
int p=0,ch;
for(int i=0;i<s.size();i++){
ch=s[i]-'a';
if(!tr[p].mp[ch]){
tr[p].mp[ch]=++cnt;//新的节点
}
p=tr[p].mp[ch];
}
tr[p].ending++;
}
查询
与构造相似
int query(string s){
int p=0,ch;
for(int i=0;i<s.size();i++){
ch=s[i]-'a';
if(!tr[p].mp[ch]){
return -1;//查询失败
}
p=tr[p].mp[ch];
}
return tr[p].ending;
}
例题
P2536
题目描述
每个 DNA 片段都是由 A、C、T、G 组成的序列。科学家们也总结出了 Samuel 星球上的“病毒模版片段”。一个模版片段是由 A、C、T、G 的序列加上通配符 * 和 ? 来表示。其中 * 的意思是可以匹配上 0 个或任意多个字符,而 ? 的意思是匹配上任意一个字母。
如果一个 DNA 片段能够和“病毒模版片段”相匹配,那么这个 DNA 片段就是未知的病毒。
例如,假设 “病毒模版片段”为 A*G?C。DNA 片段:AGTC,AGTGTC 都是未知的病毒,而 DNA 片段 AGTGC 则不是病毒。
由于,机器人搜集的这些 DNA 片段中除去病毒的其他部分都具有非常高的研究价值。所以科学家们希望能够分辨出其中哪些 DNA 片段不是病毒,并将不是病毒的 DNA 片段运回宇宙空间站继续进行研究。
科学家将这项任务交给了小联。现在请你为小联编写程序统计哪些 DNA片段不是病毒。
[!NOTE]
对于所有数据,
0 < N (DNA片段个数) < 500。
特别的:
每个 DNA 片段的长度不超过500;
“病毒模版片段”和 DNA 片段的长度都至少为1。
思路
- 对于
?,直接判断当前位置是否有指向A、C、T、G的路径。 - 对于
*,可以当作空串跳过或当作'?'+'*'处理。即dfs(i,tr[p].next)或dfs(i+1,tr[p].next)。 - 对于
A、C、T、G,向下搜索。 - 对当前情况进行标记,防止重复搜索。
AC代码
#include<bits/stdc++.h>
using namespace std;
const int N=3e5+5;
int n,cnt=0,anss=0;
map<char,int> c;
string ans,s;
struct node{
int mp[4],ending;
}tr[N];
bool vis[1005][N];
void add(string s){//Trie构造
int p=0,ch;
for(int i=0;i<s.size();i++){
ch=c[s[i]];
if(!tr[p].mp[ch]){
tr[p].mp[ch]=++cnt;
}
p=tr[p].mp[ch];
}
tr[p].ending++;
}
void dfs(int i,int p){//病毒串位置i,Trie位置p
if(i==ans.size()){
anss+=tr[p].ending;
tr[p].ending=0;//防止重复计算
return ;
}
if(vis[i][p]){
return ;
}
vis[i][p]=1;//标记处理
if(ans[i]=='*'){
dfs(i+1,p);//当作空串
for(int j=0;j<4;j++){
if(tr[p].mp[j]){
dfs(i,tr[p].mp[j]);//当作'?'+'*'
}
}
return ;
}
if(ans[i]=='?'){
for(int j=0;j<4;j++){
if(tr[p].mp[j]){
dfs(i+1,tr[p].mp[j]);
}
}
return ;
}
int ch=c[ans[i]];
if(tr[p].mp[ch]){
dfs(i+1,tr[p].mp[ch]);
}
}
int main(){
c['A']=0,c['C']=1,c['T']=2,c['G']=3;//初始化
cin>>s;
for(int i=0;i<s.size();i++){
if(i>=1&&s[i]==s[i-1]&&s[i]=='*'){
continue;
}
ans+=s[i];
}
//处理连续‘*’情况
cin>>n;
for(int i=1;i<=n;i++){
cin>>s;
add(s);
}
dfs(0,0);
cout<<n-anss<<endl;//输出不是病毒的数量
return 0;
}

浙公网安备 33010602011771号