基本功能
1.字典树插入字符串。
2.字典树中查询字符串是否出现。
3.输出字典树中已存字符串以及出现次数。
4.在字典树中删除字符串,字符串不存在提示错误。
代码
#include<bits/stdc++.h>
using namespace std;
const int bas=26;//字符集数量
#define dt(c,n,s) Data_type(c,n,s)
struct Data_type{
char c;//字符
int num;//出现次数
int s;//作为词尾出现的次数
Data_type(){};
Data_type(char tc, int tnum, int ss){
c=tc; num=tnum; s=ss;
}
};
struct node{
Data_type data;
node *a[bas];
};
void add_node(node *s, Data_type x){
node *temp=new node;
temp->data= x;
for(int i=0;i<bas;i++){
temp->a[i]=NULL;
}
s->a[x.c-'a']=temp;
}
struct tire{
node *root;
void init(){
root=new node;
root->data.num=0;
root->data.s=0;
for(int i=0;i<bas;i++){
root->a[i]=NULL;
}
}
int add_string(string s){//插入字符串s并返回插入后s出现的次数
node *now=root;
now->data.num++;
for(int i=0;i<s.length();i++){
if(now->a[s[i]-'a']==NULL){
add_node(now,dt(s[i],0,0));
}
now=now->a[s[i]-'a'];
now->data.num++;
now->data.c=s[i];
}
now->data.s++;
return now->data.s;
}
int add_string(char *s){
int n=strlen(s);
node *now=root;
for(int i=0;i<n;i++){
if(now->a[s[i]-'a']==NULL){
add_node(now,dt(s[i],0,0));
}
now=now->a[s[i]-'a'];
now->data.num++;
now->data.c=s[i];
}
now->data.s ++;
return now->data.s;
}
int query(string s){
node *now=root;
for(int i=0;i<s.length();i++){
if(now->a[s[i]-'a']==NULL) return 0;
now=now->a[s[i]-'a'];
}
return now->data.s;
}
int query(char *s){
node *now=root;
int n=strlen(s);
for(int i=0;i<n;i++){
if(now->a[s[i]-'a']==NULL) return 0;
now=now->a[s[i]-'a'];
}
return now->data.s;
}
void del(node *h, char *s, int t){//从头删除
if(s[0]=='\0'||h==NULL) {
h->data.num -=t;
h->data.s -=t;
if(h->data.num==0)free(h);
return;
}
del(h->a[s[0]-'a'], s+1, t);
if(h->a[s[0]-'a']->data.num==0){
h->a[s[0]-'a']=NULL;
}
}
int del(char *s, int t){//删除t个字符串s,返回实际删除个数
int ret=t, n=strlen(s);
if(n==0)return t;//字符串为空则直接返回
node *now=root;
for(int i=0;i<n;i++){
if(now->a[s[i]-'a']==NULL)return 0;//字符串在树中不存在,删除失败
now=now->a[s[i]-'a'];
}
ret=min( t, now->data.s);
del(root, s, ret);
return ret;
}
char pr[100052]={0};//字符串最大长度
void dfs(node *x,int len){
if(x->data.s!=0){
for(int i=0;i<len;i++){
printf("%c",pr[i]);
}
printf(" (*%d)\n",x->data.s);
}
for(int i=0;i<bas;i++){
if(x->a[i]==NULL)continue;
pr[len]=x->a[i]->data.c;
dfs(x->a[i],len+1);
}
}
void print(){//打印字典树中所有字符串
dfs(root,0);
}
};
char s[10000];
int op;
int main(){
tire tr;
tr.init();
while(1){
scanf("%d",&op);
if(op==0){
scanf("%s",s);
tr.add_string(s);
}
if(op==1){
tr.print();
}
if(op==2){
scanf("%s",s);
printf("num= %d\n",tr.query(s));
}
if(op==3){
scanf("%s",s);
int ans=tr.del(s,1);
if(ans==0) printf("error\n");
else printf("successful\n");
}
}
return 0;
}
待加功能:
5.返向连接Fail 边,跑 AC自动机 匹配字符串。