• 前缀树


    前缀树又称为字典树,接触这个数据结构是因为在 LeetCode 上面刷到这道题 14. Longest Common Prefix。然后,我去看了下官方推荐的文章以及其他人的博客,基本上是可以理解这种数据结构的吧!
    下面就贴下这种数据结构的一种实现的代码吧:
    节点类:

    package ds;
    
    /**
     * Created by clearbug on 2018/3/6.
     *
     * 字典树节点类
     */
    public class TrieNode {
    
        // R links to node children
        private TrieNode[] links;
    
        private final int R = 26;
    
        private boolean isEnd;
    
        // number of children non null links
        private int size;
    
        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;
            size++;
        }
    
        public int getLinks() {
            return size;
        }
    
        public void setEnd() {
            isEnd = true;
        }
    
        public boolean isEnd() {
            return isEnd;
        }
    
    }
    

    字典树类:

    package ds;
    
    /**
     * Created by clearbug on 2018/3/6.
     *
     * 字典树
     */
    public class Trie {
    
        private 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++) {
                char currentChar = word.charAt(i);
                if (!node.containsKey(currentChar)) {
                    node.put(currentChar, new TrieNode());
                }
                node = node.get(currentChar);
            }
            node.setEnd();
        }
    
        // search a prefix or whole key in trie and returns the node where search ends
        private TrieNode searchPrefix(String word) {
            TrieNode node = root;
            for (int i = 0; i < word.length(); i++) {
                char curLetter = word.charAt(i);
                if (node.containsKey(curLetter)) {
                    node = node.get(curLetter);
                } else {
                    return null;
                }
            }
            return node;
        }
    
        // Returns if the word is in the trie.
        public boolean search(String word) {
            TrieNode node = searchPrefix(word);
            return node != null && node.isEnd();
        }
    
        // Returns is there is any word in the trie that starts with the given prefix.
        public boolean startsWith(String prefix) {
            TrieNode node = searchPrefix(prefix);
            return node != null;
        }
    
        // just for https://leetcode.com/problems/longest-common-prefix/description/
        private String searchLongestPrefix(String word) {
            TrieNode node = root;
            StringBuilder prefix = new StringBuilder();
            for (int i = 0; i < word.length(); i++) {
                char curLetter = word.charAt(i);
                if (node.containsKey(curLetter) && (node.getLinks() == 1) && (!node.isEnd())) {
                    prefix.append(curLetter);
                    node = node.get(curLetter);
                } else {
                    return prefix.toString();
                }
            }
            return prefix.toString();
        }
    
    }
    

    测试一把:

    import ds.Trie;
    
    /**
     * Created by clearbug on 2018/3/6.
     */
    public class Test {
    
        public static void main(String[] args) {
            String[] words = {"are", "you", "ok"};
            String[] words2 = {"yes", "no"};
    
            Trie trie = new Trie();
            for (int i = 0; i < words.length; i++) {
                trie.insert(words[i]);
            }
    
            for (int i = 0; i < words.length; i++) {
                System.out.println("Search "" + words[i] + "" result: " + trie.search(words[i]));
            }
            for (int i = 0; i < words2.length; i++) {
                System.out.println("Search "" + words2[i] + "" result: " + trie.search(words2[i]));
            }
        }
    }
    

    运行结果:

    Search "are" result: true
    Search "you" result: true
    Search "ok" result: true
    Search "yes" result: false
    Search "no" result: false
    

    参考

    https://leetcode.com/articles/implement-trie-prefix-tree/
    https://www.cnblogs.com/grandyang/p/4491665.html

  • 相关阅读:
    Matlab从入门到精通 Chapter5 数据可视化
    给source insight添加.cc的C++文件后缀识别
    机构研究报告
    配置Haproxy
    Ceph:一个 Linux PB 级分布式文件系统
    Centos安装源包出错Package xxx.rpm is not signed
    [虚拟机] 小实验: 使用KVM虚拟机,安装一个windows系统
    关于北京地铁通车计划
    python字符串和数字的基本运算符 valar
    python种类 valar
  • 原文地址:https://www.cnblogs.com/optor/p/8513547.html
Copyright © 2020-2023  润新知