• 跟左神学算法8 进阶数据结构(前缀树)


    内容:

    1、前缀树详解

    2、如何生成前缀树

    3、前缀树应用

    1、前缀树详解

    什么是前缀树:

    前缀树又称字典树、Trie树,是一种树形结构,是哈希树的变种,是一种用于快速检索的多叉树结构
    典型应用是用于统计和排序大量的字符串(不限于字符串),经常被搜索引擎系统用作文本词频统计
    优点是可以最大限度地减少无谓地字符串比较,查询效率高

    前缀树的特点:

    • 根节点不包含字符,除根节点外的每一个子节点都包含一个字符
    • 从根节点到某一节点的路径上的路径上的字符连接起来就是该节点对应的字符串
    • 每个节点的所有子节点包含的字符都不相同

    2、如何生成前缀树

    前缀树:实际上就是一个森林

    生成前缀树:

      1 public class trieTree{    
      2     // the node of trie
      3     public static class TrieNode {
      4         // path: string arrive the node
      5         // end: string end in the node
      6         // nexts: next nodes
      7         public int path;
      8         public int end;
      9         public HashMap<Character, TrieNode> nexts;
     10 
     11         public TrieNode() {
     12             path = 0;
     13             end = 0;
     14             nexts = new HashMap<Character, TrieNode>();
     15         }
     16     }
     17     
     18     
     19     // the trie
     20     public static class Trie {
     21         private TrieNode root;        // the root of trie
     22 
     23         public Trie() {
     24             root = new TrieNode();
     25         }
     26 
     27         // insert a word to a trie
     28         public void insert(String word) {
     29             if (word == null) {
     30                 return;
     31             }
     32             char index;
     33             char[] chs = word.toCharArray();
     34             TrieNode node = root;
     35             for (int i = 0; i < chs.length; i++) {
     36                 index = chs[i];
     37                 if (node.nexts.get(index) == null) {
     38                     node.nexts.put(index, new TrieNode());
     39                 }
     40                 node = node.nexts.get(index);
     41                 node.path++;
     42             }
     43             node.end++;
     44         }
     45         
     46         // search a word in a trie(similar to insert)
     47         public int search(String word) {
     48             if (word == null) {
     49                 return 0;
     50             }
     51             char index;
     52             char[] chs = word.toCharArray();
     53             TrieNode node = root;
     54             for (int i = 0; i < chs.length; i++) {
     55                 index = chs[i];
     56                 if (node.nexts.get(index) == null) {
     57                     return 0;
     58                 }
     59                 node = node.nexts.get(index);
     60             }
     61             return node.end;
     62         }
     63 
     64         // delete a word to a trie(similar to insert)
     65         public void delete(String word) {
     66             if(search(word) != 0){
     67                 char index;
     68                 char[] chs = word.toCharArray();
     69                 TrieNode node = root;
     70                 for (int i = 0; i < chs.length; i++) {
     71                     index = chs[i];
     72                     if (--node.nexts.get(index).path == 0) {
     73                         node.nexts.remove(index);
     74                         return;
     75                     }
     76                     node = node.nexts.get(index);
     77                 }
     78                 node.end--;
     79             }
     80         }
     81         
     82         // get the pre in trie's fixNumber(similar to search)
     83         public int prefixNumber(String pre){
     84             if(pre==null){
     85                 return 0;
     86             }
     87             char index;
     88             char[] chs = pre.toCharArray();
     89             TrieNode node = root;
     90             for (int i = 0; i < chs.length; i++) {
     91                 index = chs[i];
     92                 if (node.nexts.get(index) == null) {
     93                     return 0;
     94                 }
     95                 node = node.nexts.get(index);
     96             }
     97             return node.path;
     98         }    
     99     }
    100 }

    3、前缀树应用

    问题描述:

    1、arr2中有哪些字符,是arr1中出现的?请打印
    2、arr2中有哪些字符,是作为arr1中某个字符串前缀出现的?请打印
    3、arr2中有哪些字符,是作为arr1中某个字符串前缀出现的?请打印arr2中出现次数最大的前缀

    解决思路:

    借助上述实现的前缀树

    代码:

     1 Trie trie = new Trie();
     2 for(int i=0; i<arr1.length; i++){
     3     trie.insert(arr1[i]);
     4 }
     5 
     6 // 打印arr2中出现在arr1中的字符串
     7 for(int i=0; i<arr2.length; i++){
     8     if(trie.search(arr2[i]) != 0){
     9         System.out.print(arr2[i] + " ");
    10     }
    11 }
    12 System.out.println();
    13 
    14 // 打印arr2中作为arr1中某个字符串前缀出现的字符串
    15 for(int i=0; i<arr2.length; i++){
    16     if(trie.prefixNumber(arr2[i]) != 0){
    17         System.out.print(arr2[i] + " ");
    18     }
    19 }
    20 System.out.println();
    21 
    22 // 打印arr2中作为arr1中某个字符串前缀出现次数最大的字符串
    23 int index = -1, max = 0;
    24 for(int i=0; i<arr2.length; i++){
    25     int times = trie.prefixNumber(arr2[i]);
    26     if(times > max){
    27         max = times;
    28         index = i;
    29     }
    30 }
    31 System.out.println(arr2[index]);
    32 System.out.println();
  • 相关阅读:
    vue-org-tree 组织结构树插件
    vue-pdf 插件预览
    element upload 上传报错 Uncaught TypeError: Cannot set property 'status' of undefined
    element 表格回显默认选中的一行在第一行显示
    swiper轮播图(中间大,两侧小)
    elementui 树控件默认隐藏第三级菜单
    Echarts配置项详解
    elementui禁用树形结构全部复选框
    layui下拉多选formSelects使用方法
    R语言 expression函数
  • 原文地址:https://www.cnblogs.com/wyb666/p/10195322.html
Copyright © 2020-2023  润新知