Trie 树

Trie 树 ,又叫字典树,前缀树(prefix Tree)、单词查找树 或键树,是一种多叉树结构。如图:

在这里插入图片描述
表示关键字集合 {‘a’,‘to’,‘tea’,‘ted’,‘i’,‘in’,‘inn’}。Trie树的基本性质:

  1. 根节点不包含字符,除根节点外的每一个子节点都包含一个字符
  2. 从根节点到某一个节点,路径上经过的字符连接起来,为该字节对应的字符串。
  3. 每一节点的所有子节点包含的字符互不相同。

通常在实现的时候,会在节点结构中设置一个标志,用来标记该节点处是否构成一个单词(关键字)。

208. 实现 Trie (前缀树)

本题为构建一个Trie树,其中3个操作,insert 、search 、startWith。search 是查询输入的单词是不是插入Trie过,startWith是看看有没有相同的前缀,比如apple ,app就是它的一个前缀。

代码如下:


class Trie(object):

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.root={}
        

    def insert(self, word):
        """
        Inserts a word into the trie.
        :type word: str
        :rtype: None
        """
        node=self.root
        for c in word:
            if c not in node:
                node[c]={}
            node=node[c]
        node['is_word']=True          #将单词的最后一个字符设置标志位,它的键中‘is_word’对应的值为True        
        
    def search(self, word):
        """
        Returns if the word is in the trie.
        :type word: str
        :rtype: bool
        """
        node=self.root
        for c in word:
            if c not in node:
                return False
            node=node[c]
        if 'is_word' in node:
            return  node['is_word']
        else:
            return False
        

    def startsWith(self, prefix):
        """
        Returns if there is any word in the trie that starts with the given prefix.
        :type prefix: str
        :rtype: bool
        """
        node=self.root
        for c in  prefix:
            if c not in node:
                return False
            node=node[c]
        return True

python 使用嵌套字典来实现树结构,对于非ascii的单词,统一使用unicode编码来插入和与搜索。
字典树常用做高效的文本词语保存,适用于敏感词过滤、关键词提取等场景。在字典树中相同前缀的词之间共享相同的树节点和路径。

#通过字典的嵌套来实现
class Trie():
    """
    1.根据一组words进行TrieTree的构建
    2.添加某个word
    3.查询某个word
    4.删除某个word

    """
    def __init__(self):
        self.trie = {}
        self.count = 0
    
    def __repr__(self):
        return str(self.trie)
    
    def buildTree(self,wordlist):
        for word in wordlist:
            t=self.trie
            for w in word:
                if w not in t:
                    t[w]={'count':0,'end':False}
                t[w]['count']+=1
                t=t[w]
            self.count+=1
            t['end']=True
    def add(self,word):
        t=self.trie
        for w in word:
            if w not in t:
                t[w]={'count':0,'end':False}
            t[w]['count']+=1
            t=t[w]

        self.count+=1
        t['end']=True

    def delete(self,word):#仅仅改变end和count属性,字符串仍存在于存储中, 先确定是否存在,若存在沿着的每条路径的count都需要-1
        if not self.search(word):
            return False
        t=self.trie
        for w in word:
            t=[w]
            t['count']-=1
        self.count-=1
        t['end']=False


    def search(self,word):
        t=self.trie
        for w in word:
            if w not in t:
                return False
            t=t[w]
        if t.get('end'):
            return True
        return False


    def prefix_count(self,prefix):
        t=self.trie
        for w in prefix:
            if w not in t:
                return -1
            t=t[w]
        if not  t['end']:
            return 0
        return t['count']


if __name__=="__main__":
    Text = ['b','abc','abd','bcd','abcd','efg','hii','bcd']
    t=Trie()
    t.buildTree(Text)
    print(t.prefix_count('bcd'))


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值