字典树的插入查询和删除字串操作

Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀). 
Input输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给111统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串. 

注意:本题只有一组测试数据,处理到文件结束. 
Output对于每个提问,给出以该字符串为前缀的单词的数量. 
Sample Input
banana
band
bee
absolute
acm

ba
b
band
abc
Sample Output
2
3
1
0
 
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=1e6+100;
int a[maxn][26];
int k[maxn];
bool vis[maxn]; 
char t[maxn];
int cnt;
void build(){
    int p=0;
    for(int i=0;i<strlen(t);i++){
        int c=t[i]-'a';
        if(!a[p][c]){ a[p][c]=++cnt;};
        p=a[p][c];
        k[p]++;
    }
    vis[p]=1;
}
int query(){
    int ans=0;
    int p=0;
    for(int i=0;i<strlen(t);i++){
        int c=t[i]-'a';
        if(!a[p][c]) return 0;
        p=a[p][c];
    }
    return k[p];
}
int main(){
    while(gets(t)){
        int len=strlen(t);
        if(len==0){
            break;
        }
        build();
    }
    while(gets(t)){
        int ans=query();
        cout<<ans<<endl;
    }
} 

 

 
 
 
 
 
度熊手上有一本神奇的字典,你可以在它里面做如下三个操作: 

  1、insert : 往神奇字典中插入一个单词 

  2、delete: 在神奇字典中删除所有前缀等于给定字符串的单词 

  3、search: 查询是否在神奇字典中有一个字符串的前缀等于给定的字符串 

Input这里仅有一组测试数据。第一行输入一个正整数N(1N100000)N(1≤N≤100000),代表度熊对于字典的操作次数,接下来NN行,每行包含两个字符串,中间中用空格隔开。第一个字符串代表了相关的操作(包括: insert, delete 或者 search)。第二个字符串代表了相关操作后指定的那个字符串,第二个字符串的长度不会超过30。第二个字符串仅由小写字母组成。Output对于每一个search 操作,如果在度熊的字典中存在给定的字符串为前缀的单词,则输出Yes 否则输出 No。Sample Input

5
insert hello
insert hehe
search h
delete he
search hello

Sample Output

Yes
No

Sponsor

 

插入和查询都好说,就是这个删除。。。。。

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=1e6+100; 
const int maxx=1e5+100;
int t[maxn][30]; 
int k[maxn];
char a[maxx];
int cnt=0;
void build(int len){
    int p=0;
    for(int i=0;i<len;i++){
        int c=a[i]-'a';
        if(!t[p][c]){
            t[p][c]=++cnt;
        }
        p=t[p][c];
        k[p]++;
    } 
}

int query(int len){
    int p=0;
    for(int i=0;i<len;i++){
        int c=a[i]-'a';
        if(!t[p][c]){
            return 0;
        }
        p=t[p][c];
    }
    return k[p];
}

void del(int len){
    int p=0;
    for(int i=0;i<len;i++){
        int c=a[i]-'a';
        if(!t[p][c]){
            return ;
        }
        p=t[p][c];
    }
    int num=k[p];
    p=0;
    for(int i=0;i<len;i++){
        int c=a[i]-'a';
        p=t[p][c];
        k[p]-=num;
    }
    for(int i=0;i<=25;i++){
        t[p][i]=0;
    }
}
int main(){
    int kase;
    cin>>kase;
    for(int i=1;i<=kase;i++){
        char b[10];
        scanf("%s%s",b,a);
        int len=strlen(a);
        if(b[0]=='i'){
            build(len);
        }
        else if(b[0]=='s'){
            int p=query(len);
            if(p==0){
                printf("No\n");
            }
            else{
                printf("Yes\n");
            }
        }
        else if(b[0]=='d'){
            del(len);
        }
    } 
}

 

posted @ 2021-05-05 11:26  lipu123  阅读(195)  评论(0)    收藏  举报