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;
    }

    }

    }

    /* 如有意见或建议,欢迎评论区留言;如发现代码有误,欢迎批评指正 */
  • 相关阅读:
    Navicat for SQLite之外键(05)
    UIButton
    多线程中的API
    UIImageView
    IOS中实现单例
    IOS中的多线程【二】— NSOperation和NSOperationQueue
    IOS中的多线程
    OC中新增的数据类型
    【转】c# DBF数据库导入导出实例
    【经验】学习新知识的经验
  • 原文地址:https://www.cnblogs.com/laydown/p/12823642.html
Copyright © 2011-2022 走看看