【11月LeetCode组队打卡】Task2--TrieTree

发布时间 2023-11-19 17:20:37作者: Wennz-y

字典树Trie

  • 音同try,又称前缀树,是一颗有根树,根节点到树节点的一个路径就代表一个单词,多用于关键词检索,自动补完和拼写检查

  • 用空间换时间:借公共前缀来降低查询时间的开销

  • 根节点无内容

(参考:
字典树TrieTree图文详解——CSDN

实现Trie题解——力扣

208.实现Trie

复习一下this指针:

  • cpp给每个非静态的成员函数都增加了一个隐藏(不能显式地写出来)的指针参数this,指向当前对象

  • 在函数体中所有成员变量的操作都是通过该指针访问

  • 是个形参,存储在栈区(寄存器register)

成员变量(Private):

  • 节点两个字段:
    • 指向子节点的指针数组children
    • 布尔字段isEnd

功能函数(public):

  • 插入insert:

    • 存在children--沿指针移动

    • 不存在--创建,记录在children数组对应位置上

  • 查询search:

    • 存在children--后移

    • 存在prefix--后移

    • 存在字符串--前缀末尾对应节点的isEnd为true

    • 不存在--prefix不匹配

  • 查找前缀prefix:

    • 存在children--后移

    • 不存在--说明字典树中不包含该前缀,返回空指针nullptr

  • 析构函数deconstruction:

    • trie对象没有析构函数,用的默认析构函数。new出来的对象不delete释放内存,多了会泄露

AC:vector数组构建Trie

#include<iostream>
#include<string>
#include<vector>
using namespace std;

//vector动态数组方法
class Trie {
private:
    //两个字段
    vector<Trie*> children;
    bool isEnd;

    Trie* searchPrefix(string prefix){
        Trie* node=this;
        //this pointer, Trie* type
        for(char ch:prefix){
            //借ASCII码求字符下标,将字母转为数字
            ch-='a';            
            //某字符不存在于前缀中
            if(node->children[ch]==nullptr)
                return nullptr;
            //存在则后移 
            node=node->children[ch];
        }
        return node;
    }

public:
    //construction
    Trie():children(26),isEnd(false) {}

    void insert(string word) {
        Trie* node=this;
        for(char ch:word){
            ch-='a';
            if(node->children[ch]==nullptr)
                node->children[ch]=new Trie();
            //存在或生成子节点后后移
            node=node->children[ch];
        }
        node->isEnd=true;//prefix前缀的末尾
    }

    bool search(string word) {
        Trie* node=this->searchPrefix(word);
        return node!=nullptr && node->isEnd;
    }

    bool startsWith(string prefix) {
        return this->searchPrefix(prefix)!=nullptr;
    }
};

int main(){
    Trie* object;
    object=new Trie();
    object->insert("hello");
    bool flag;
    flag=object->search("hello");
    if(flag)
        cout<<"word exists";
    else    cout<<"word does not exist";
    return 0;
}

vocal,真??

Java版本(实现了数组和哈希两种方式的Trie)

数组

public  class Trie{
    class TrieNode{
        TrieNode son[];
        boolean idEnd;
        public TrieNode()
        {
            son=new TrieNode[26];
        }
    }
    TrieNode root;
    //初始化
    public Trie()
    {
        root=new TrieNode();
    }

/** Inserts a word into the trie. */
public void insert(String word) {
    TrieNode node=root;//临时节点用来枚举
    for(int i=0;i<word.length();i++)//枚举字符串
    {
        int index=word.charAt(i)-'a';//找到26个对应位置
        if(node.son[index]==null)//如果为空需要创建
        {
            node.son[index]=new TrieNode();
        }
        node=node.son[index];
    }
    node.isEnd=true;//最后一个节点
}

public boolean search(String word) {
    TrieNode node=root;
    for(int i=0;i<word.length();i++)
    {
        int index=word.charAt(i)-'a';
        if(node.son[index]==null)//为null直接返回false
        {
            return false;
        }
        node=node.son[index];
    }
    return node.isEnd==true;
}

public boolean startsWith(String prefix) {
    TrieNode node=root;
    for(int i=0;i<prefix.length();i++)
    {
        int index=prefix.charAt(i)-'a';
        if(node.son[index]==null)
        {
            return false;
        }
        node=node.son[index];
    }
  //能执行到最后即返回true
    return  true;
  }
}

哈希表

import java.util.HashMap;
import java.util.Map;

public  class Trie{
    class TrieNode{
        Map<Character,TrieNode> sonMap;
        boolean idEnd;
        public TrieNode()
        {
            sonMap=new HashMap<>();
        }
    }
    TrieNode root;
    public Trie()
    {
        root=new TrieNode();
    }

    public void insert(String word) {
        TrieNode node=root;
        for(int i=0;i<word.length();i++)
        {
            char ch=word.charAt(i);
            if(!node.sonMap.containsKey(ch))
            //不存在插入
            {
                node.sonMap.put(ch,new TrieNode());
            }
            node=node.sonMap.get(ch);
        }
        node.idEnd=true;
    }

    public boolean search(String word) {
        TrieNode node=root;
        for(int i=0;i<word.length();i++)
        {
            char ch=word.charAt(i);
            if(!node.sonMap.containsKey(ch))
            {
                return false;
            }
            node=node.sonMap.get(ch);
        }
        return node.idEnd==true;
        //必须标记为true证明有该字符串
    }


    public boolean startsWith(String prefix) {
        TrieNode node=root;
        for(int i=0;i<prefix.length();i++)
        {
            char ch=prefix.charAt(i);
            if(!node.sonMap.containsKey(ch))
            {
                return false;
            }
            node=node.sonMap.get(ch);
        }
        return true;
        //执行到最后一步即可
    }
}