首页 > 其他分享 >10-前缀树

10-前缀树

时间:2023-11-09 09:13:16浏览次数:42  
标签:10 end 前缀 nexts str pass curIndex cur

10. 前缀树(trie)

8.1 前缀树概念

1. 前缀树概念

1)单个字符串中,字符从前到后的加到一棵多叉树上

2)字符放在路上,节点上有专属的数据项

数据项pass:有多少路径经过了这个点

数据项end:有多少路径是以这个点结尾

3)所有样本都这样添加,如果没有路就新建,如有路就复用

4)沿途节点的pass值增加1,每个字符串结束时来到的节点end值增加1

2. 前缀树使用范围

求在一个字符数组中,某一个字符串出现的次数(查看数中有没有这一分支,如果有是否end不为0)

求在一个字符数组中,包含某一个字符串出现的次数(查看数中有没有这一分支,如果有是否pass不为0)

8.2 前缀树

1. 题目

建立前缀树,并且完成增删字符串的功能

2. 思路

  1. 每个节点至少有三部分组成,pass,end,Nodes,需要注意,对于长度为n的字符串,节点要有n+1个

数据项pass:有多少路径经过了这个点

数据项end:有多少路径是以这个点结尾

节点项next:存放26个节点,每个位置代表一个字母new Node[26];

  1. 添加

​ 给所有路径上的节点加1,如果没有的话,就建立个新的节点加进去。最后一位end+1。

  1. 查找

​ 查找路径,直到节点为空或者找到的位置end为0或者找到的位置end大于0(完成)

  1. 查找部分

​ 查找部分路径,如果pass > 0,找到。

  1. 删除

​ 删除路径,找到某个pass为0的地方,删除。或者如果找到最后end大于0,end--。

3. 代码

节点:

class Node {
    int pass;
    int end;
    Node[] nexts;
    public Node(){
        this.pass = 0;
        this.end = 0;
        nexts = new Node[26];
    }
}

TrieTree初始化:

private Node root;
public TrieTree(){
    root = new Node();
}

插入:

public void insert(String word){
    if(word == null){
        return;
    }

    char[] str = word.toCharArray();
    Node cur = root;
    // 从上往下遍历,有就加,没有就新建
    for (int i = 0; i < str.length; i++) {
        cur.pass++;
//            System.out.println(cur.pass+" "+ str[i]+" "+cur.end);
        int curIndex = str[i]-'a';
        if(cur.nexts[curIndex] == null){
            cur.nexts[curIndex] = new Node();
        }
        cur = cur.nexts[curIndex];
    }
    cur.pass++;
    cur.end++;
}

查询:

// 查看这个单词出现了几次
public int search(String word){
    if(word == null){
        return 0;
    }
    char[] str = word.toCharArray();
    Node cur = root;
    // 从上往下遍历,有就加,没有就新建
    for (int i = 0; i < str.length; i++) {
        int curIndex = str[i]-'a';
        if(cur.nexts[curIndex] == null){
            return 0;
        }
        cur = cur.nexts[curIndex];
    }
    return cur.end;
}

查询前缀:

// 所有加入的字符串中,有几个是以pre这个字符串作为前缀的
public int prefixNumber(String word){
    if(word == null){
        return 0;
    }
    char[] str = word.toCharArray();
    Node cur = root;
    // 从上往下遍历,有就加,没有就新建
    for (int i = 0; i < str.length; i++) {
        int curIndex = str[i]-'a';
        if(cur.nexts[curIndex] == null){
            return 0;
        }
        cur = cur.nexts[curIndex];
    }
    return cur.pass;
}

删除:

// 删除某个字符串
public void delete(String word){
    // 如果删除的字符存在
    if(search(word) != 0){
        char[] str = word.toCharArray();
        Node cur = root;
        // 从上往下遍历,
        for (int i = 0; i < str.length; i++) {
            cur.pass--;
            int curIndex = str[i]-'a';
            if(cur.nexts[curIndex].pass == 1){
                cur.nexts[curIndex] = null;
                return;
            }
            cur = cur.nexts[curIndex];
        }
        cur.pass--;
        cur.end--;
    }
}

标签:10,end,前缀,nexts,str,pass,curIndex,cur
From: https://www.cnblogs.com/ylw-blogs/p/17818908.html

相关文章

  • Ubuntu LTS 坚持 10 年更新不动摇
    Linux 内核开发者JonathanCorbet此前在欧洲开源峰会上宣布,LTS内核的支持时间将从六年缩短至两年,原因在于缺乏使用和缺乏支持。稳定版内核维护者GregKroah-Hartman也表示“没人用LTS内核”。近日,Ubuntu开发商Canonical发表博客称,他们会坚持为UbuntuLTS版本......
  • Delphi10.4 Android调用相机返回图片调试
    Delphi10.4Android调用相机返回图片调试使用Delphi封装的“StandardAction”这些标准操作,可以非常方便我们调用Android系统功能。在Android上会存在各类权限问题造成应用无法运行创建工程 File->New->Multi-DeviceApplication-Delphi选择" BlankApplication",点击"OK"完成......
  • 20231108数数与dp题笔记
    数数与dpCF294CShaassandLights记被分成的\(m+1\)段每一段的长度为\(l_i\)答案为\[\frac{(n-m)!}{\prod\limits_{i=1}^{m+1}l_i!}\times\prod\limits_{i=1}^{m+1}2^{l_i-1}\]前面是不同段之间的顺序打乱,后面是每一段中前\(l_i-1\)个操作各有\(2\)个选择CF1753CW......
  • openEuler22.03操作系统 Linux内核Kernel 5.10 应该选择哪个版本的mysql安装包下载?
    对于openEuler22.03操作系统和Linux内核Kernel5.10,你应该选择与该操作系统和内核版本兼容的MySQL安装包进行安装。在确定适合的MySQL版本时,你可以考虑以下几点:MySQL官方支持:查看MySQL官方网站中的文档或支持页面,确认其是否支持openEuler22.03操作系统和Kernel5.......
  • GYM103102/SEERC2020 J One Piece
    GYM103102/SEERC2020JOnePiece这题讲杂题的时候人没讲清楚,下来问做出来的大佬也没说清楚,网上翻半天题解一两句没了,心态炸了都。题意略过,各位自己去看一遍原题目。提前约定一些符号:\(\operatorname{dis}(a,b)\)表示点\(a,b\)之间的距离。首先我们设题目中给出的点\(i\)......
  • 每日总结20231108
    代码时间(包括上课)6h代码量(行):100行博客数量(篇):1篇相关事项:1、今天是周三,上午上的是软件构造,讲的是交互和测试,具体的交互内容包括和测试的方式包括。2、今天下午参加了一个电气院的用电安全知识竞赛。3、今天晚上打算复习复习数学,毕竟马上要考研。......
  • 231108校内赛
    T1最大公约数数据极水,啥都能过第一种方法,暴力剪枝,直接飞过,\(\mathcalO(N^2\logn)\)过\(30\)万不解释玛德有人在提交时不写输出直接爆零#include<bits/stdc++.h>#defineN300010usingnamespacestd;intn,k,ans,a[N];intgcd(inta,intb){ returnb==0?a:gcd(b,......
  • laravel:目录结构(10.27.0)
    一,相关文档:https://learnku.com/docs/laravel/10.x/structure/14837#c2b9f4二,app目录1,如图:2,各目录的用途:console:所有自定义的控制台命令Exceptions:异常处理器Http/Controllers:控制器  目录下的Controller.php是其他业务功能controller的基类Http/Mid......
  • laravel:自动加载自定义类(10.27.0)
    一,配置1,在laravel项目的根目录下添加extend目录,如图:2,编辑composer.json,在autoload增加一行:"":"extend/",如图:生成自动加载文件:liuhongdi@lhdpc:/data/laravel/dignews$composerdump-autoload-oGeneratingoptimizedautoloadfiles...命令的解释:将PSR-......
  • GEPCI-5565PIORC-210000反射内存卡
    反射内存实时网的特点VMIC反射内存是一种通过局域网在互连的计算机间提供的数据传输的技术,强实时网络设计人员已经越来越多地采用这种技术。VMIC反射内存实时局域网的概念十分简单,就是设计一种网络内存板,在分布系统中实现内存至内存的通信,并且没有软件开销。每台结点机上插一块反射......