古人有云:“一杯茶,一包烟,一个bug调一天。”

今天我是切身体会到代码出问题,还是在逻辑语法都没问题的情况下的心塞。后来才发现是题目提供的方法名我少写了一个"s",就是下面startswith的方法名中的s。就这一个小点,搞了3个多小时!!!!

废话不多说,我们来看看什么是前缀树:又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。

搜索字典项目的方法为:

(1) 从根结点开始一次搜索;

(2) 取得要查找关键词的第一个字母,并根据该字母选择对应的子树并转到该子树继续进行检索;

(3) 在相应的子树上,取得要查找关键词的第二个字母,并进一步选择对应的子树进行检索。

(4) 迭代过程……

(5) 在某个结点处,关键词的所有字母已被取出,则读取附在该结点上的信息,即完成查找。

其他操作类似处理。

具体的应用:串的快速检索、“串”排序、最长公共前缀

java前缀树存到redis_java前缀树存到redis


介绍完定义之后,我们来从力扣上一道题入手来编写Trie树。

leetcode208. 实现 Trie (前缀树)

链接:https://leetcode-cn.com/problems/implement-trie-prefix-tree/

难度:中等

题目:

实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作。

示例:

Trie trie = new Trie();
 trie.insert(“apple”);
 trie.search(“apple”); // 返回 true
 trie.search(“app”); // 返回 false
 trie.startsWith(“app”); // 返回 true
 trie.insert(“app”);
 trie.search(“app”); // 返回 true

方法一:

第一步我们先要构建树的结点:由题目要求可以知道

class TrieNode {
    boolean isleaf;
    Map<Character,TrieNode> next;//用来存,下一个结点的信息,K是存储字符,Value存储结点
    public TrieNode(){
        next=new HashMap<Character,TrieNode>();
    }

}

第二步构建Trie树,并实现search、insert、startswith方法

class Trie{
    private TrieNode root;//定义根节点
    public Trie(){
        root = new TrieNode();
    }
    //方法:插入方法
     public void insert(String word){
        if(word == null || word.length() == 0){
            return ;
        }
        TrieNode node = root;
        int len=word.length();
        for(int i=0;i<len;i++){
            Character c = word.charAt(i);
            TrieNode tempNode = node.next.get(c);
            if(tempNode == null){
               tempNode =  new TrieNode();
                node.next.put(c,tempNode);
            }
            node=tempNode;
        }
        node.isleaf = true;
     }

     //search方法
     public boolean search(String word){
        if(word == null || word.length() == 0){
            return false;
        }
        TrieNode node =root;
        int len=word.length();
        for(int i=0;i<len;i++){
            Character c = word.charAt(i);
            TrieNode tempNode = node.next.get(c);
            if(tempNode == null){
                return false;
            }
            node = tempNode;
        }
        return node.isleaf;
     }
    //返回trie中是否有给定前缀开头的单词
     public boolean startsWith(String prefix){
        if(prefix == null || prefix.length() == 0) return false;
        TrieNode node = root;
        int len=prefix.length();
        for(int i=0;i<len;i++){
            TrieNode tempNode = node.next.get(prefix.charAt(i));
            if(tempNode == null){
                return false;
            }
            node=tempNode;
        }
        return true;//不需要判断是否是叶结点

     }
}

方法二:
构建结点:是用数组,其实在结点构造这块,定义的方法是模拟map

class TrieNode{
    private TrieNode[] links;
    private final int R=26;
    private boolean isEnd;

    public TrieNode(){
        links=new TrieNode[][R];
    }
    public boolean containsKey(char ch){
        return links[ch-'a'] != null;
    }
    public TrieNode get(char ch){
        return links[ch-'a'];
    }
    public void put(char ch,TrieNode node){
        links[ch-'a']=node;
    }
    public void setEnd(){
        isEnd=true;
    }
    public boolean isEnd(){
        return isEnd;
    }

}

构建trie:

public class Trie {
    private TrieNode root;
    public Trie(){
        root = new TrieNode();
    }
    //inset
    public void insert(String word){
        if(word == null || word.length() == 0) return ;
        TrieNode node =root;
        for(int i=0;i<word.length();i++){
            char c = word.charAt(i);
            if(!node.containsKey(c)){
                node.put(c,new TrieNode());
            }
            node = node.get(c);//node指向下一个结点
        }
        node.setEnd();
    }
    //searchPrefix
    public TrieNode searchPrefix(String word){
        if(word == null || word.length() == 0) return false;
        TrieNode node=root;
        for(int i=0;i<word.length();i++){
            char c = word.charAt(i);
            if(node.containsKey(c)){
                node=node.get(c);
            }else{
                return null;
            }
        }
        return node;
    }

    //search
    public boolean search(String word){
        TrieNode node = searchPrefix(word);
        return node != null && node.isEnd();
    }

}

希望世界少一点bug,多一点爱!