字典树

一道机试题:写一个字典实现以下功能:

(1)插入某个字符串

(2)删除某个字符串为前缀的所有字符串

(3)搜索某个字符串为前缀的字符串,找到输出YES,否则输出NO

 

看到这个是有想到索引,但是这个前缀不太好实现,于是上网看有没有什么好的实现方式。又认识到了一种新的字典的实现方式:字典树。这个结构真的太适合有前缀的字符串存储了!!

 

字典树参见博客:https://blog.csdn.net/weixin_39778570/article/details/81990417

我在作者的基础上,改写了search函数,可以查找前缀为指定字符串的字符串。又编写了删除函数,可以删除前缀为某一特定字符串的字符串。代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int MAX_NODE = 1000000 + 10;
const int CHARSET = 26;
int trie[MAX_NODE][CHARSET] = {0};
int color[MAX_NODE] = {0};
int k = 1;

void insert(char *w){
    int len = strlen(w);
    int p = 0;
    for(int i=0; i<len; i++){
        int c = w[i] - 'a';
        if(!trie[p][c]){
            trie[p][c] = k;
            k++;
        }
        p = trie[p][c];
    }
    color[p] = 1;
}

int search(char *s){
    int len = strlen(s);
    int p = 0;
    for(int i=0; i<len; i++){
        int c = s[i] - 'a';
        if(!trie[p][c]) return 0;
        p = trie[p][c];
    }
    return 1;
}

int dele(char *s){
    int len = strlen(s);
    int p = 0;
    for (int i = 0; i < len; ++i) {
        int c = s[i] - 'a';
        if(!trie[p][c]) return 0;
        if(i != len-1)
            p = trie[p][c];
        else
            trie[p][c] = 0;
    }
    return 1;
}

int main(){
    bool flag = true;
    while (flag){
        printf("choose:1:insert\n2:delete\n3search\n4:end\n");
        int order;
        scanf("%d", &order);
        switch (order){
            case 1:{
                printf("insert num:\n");
                int num;
                scanf("%d", &num);
                char s[20];
                while(num--){
                    scanf("%s", s);
                    insert(s);
                }

            }
            case 2:{
                printf("delete num:\n");
                int num;
                scanf("%d", &num);
                char s[20];
                while(num--){
                    scanf("%s", s);
                    if(dele(s)) printf("delete successfully!\n");
                    else printf("delete failed!\n");
                }
            }
            case 3:{
                printf("search num:\n");
                int num;
                scanf("%d", &num);
                char s[20];
                while(num--){
                    scanf("%s", s);
                    if(search(s)) printf("YES\n");
                    else printf("NO\n");
                }
            }
            case 4: flag = false;
        }
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值