zoukankan      html  css  js  c++  java
  • 字典树(前缀树)


    import java.util.HashMap;

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

    /**
    * 多叉树
    */
    public static class Node {

    public int pass;

    public int end;

    public HashMap<Integer, Node> nexts;

    public Node() {
    nexts = new HashMap<>();
    }

    }

    /**
    * 前缀树
    */
    public static class Trie {

    public Node root;

    public Trie() {
    root = new Node();
    }

    /**
    * 往树中加入一个字符串
    *
    * @param value 加入的值
    */
    public void insert(String value) {
    if (value == null) {
    return;
    }
    int ars = 0;
    Node node = root;
    node.pass++;
    char[] chars = value.toCharArray();
    for (int i = 0; i < chars.length; i++) {
    ars = (int) chars[i];
    if (!node.nexts.containsKey(ars)) {
    node.nexts.put(ars, new Node());
    }
    node = node.nexts.get(ars);
    node.pass++;
    }
    node.end++;
    }

    /**
    * 查找value字符串被加入了几次
    *
    * @param value 字符串
    * @return 加入次数
    */
    public int search(String value) {
    if (value == null) {
    return 0;
    }
    int ars = 0;
    Node node = root;
    char[] chars = value.toCharArray();
    for (int i = 0; i < chars.length; i++) {
    ars = (int) chars[i];
    if (!node.nexts.containsKey(ars)) {
    return 0;
    }
    node = node.nexts.get(ars);
    }
    return node.end;
    }

    /**
    * 删除指定字符串(如果存在)
    *
    * @param value 字符串
    */
    public void delete(String value) {
    if (search(value) == 0) {
    return;
    }
    int ars = 0;
    Node node = root;
    node.pass--;
    char[] chars = value.toCharArray();
    for (int i = 0; i < chars.length; i++) {
    ars = (int) chars[i];
    if (--node.nexts.get(ars).pass == 0) {
    node.nexts.remove(ars);
    return;
    }
    node = node.nexts.get(ars);
    }
    node.end--;
    }

    /**
    * 求所有字符串中,以pre为前缀的字符串个数
    *
    * @param pre 前缀
    * @return 个数
    */
    public int prefixNum(String pre) {
    if (pre == null) {
    return 0;
    }
    int ars = 0;
    Node node = root;
    char[] chars = pre.toCharArray();
    for (int i = 0; i < chars.length; i++) {
    ars = (int) chars[i];
    if (!node.nexts.containsKey(ars)) {
    return 0;
    }
    node = node.nexts.get(ars);
    }
    return node.pass;
    }

    }

    }

    /* 如有意见或建议,欢迎评论区留言;如发现代码有误,欢迎批评指正 */
  • 相关阅读:
    Arthas线上问题排查
    如何快速增加pdf书签,解除pdf限制
    数组指针——指向数组的指针(通过指针控制数组)
    指针和数组直接对应关系之如何记忆
    C/C++语言中指针数组和数组指针比较区别
    int最大值+1为什么是-2147483648最小值-1为什么是2147483647
    电脑进行二进制加减运算方法
    C/C++语言中的函数参数传参三种对比
    Python基于VS2013 开发环境搭建 Hello World 10分钟搞定
    算法的复杂度包括时间复杂度和空间复杂度分别如何计算?
  • 原文地址:https://www.cnblogs.com/laydown/p/12823642.html
Copyright © 2011-2022 走看看