数据结构——从英文字典树到中文字典树

面试中遇到的姓名搜索问题,初始解决方案是使用set和multimap,但后续思考发现结合字典树(Trie树)能更高效地解决姓氏搜索,尤其是对于中文姓名的处理。字典树每个节点仅含一个字符,路径字符组合成对应字符串,且子节点字符互不相同,适合姓氏检索。
摘要由CSDN通过智能技术生成

昨天面试电话中的一道题,题目如下:

1、给你一个姓名的集合,查找你的名字是否在里面出现。

我的回答是用set,把集合中所有的姓名放到set集合中,直接用find查找我的姓名在这个集合里面是否出现。

2、追问,如果要搜索姓氏为叶的人,输入关键字叶,那么会出现所有姓为叶的人,应该如何设计?

当时的回答是,姓为key,名为value,存放到multimap中,使用multimap中的count函数统计key为叶的个数,然后用find函数找到第一个key为叶的指针,使用迭代器从该指针向后查找count个元素,判断这count个元素中是否有姓名为叶x的人。后来想想我的方法其实可以优化的,网上的思路基本上都是采用字典树,但仅针对英文单词。如果把字典树和我的在面试时候的方法结合起来就非常棒了(可惜当时没想到>_<)。

什么是字典树?
Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。Trie的核心思想是空间换时间。利用 字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。
  1. 根节点不包含字符,除根节点外每一个节点都只包含一个字符。
  2. 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
  3. 每个节点的所有子节点包含的字符都不相同。
对于每个单词,如果直接去查找别的单词是否包括它,那么时间复杂度就是O(n^2),如果采用查找公共前缀,例如对于abcd,只用查找以a为前缀的节点假设为x,对于bcd,只用查找x节点中以b为前缀的节点,依次类推。
下面给出一种常见的英文字典树结构体设计:
#define MAX_CHILD 26
struct trie_node
{
    trie_node()
    {
        count = 0;

        for (int i = 0; i < MAX_CHILD; i++)
        {
            child[i] = NULL;
        }
    }
    int count;//表示以该节点结束的单词的个数
    trie_node *child[MAX_CHILD];//存放孩子节点指针的数组 
};
  • 1
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值