首页 > 其他分享 >【acwing】Trie字符串统计

【acwing】Trie字符串统计

时间:2023-06-07 16:12:34浏览次数:43  
标签:tmp Trie trie int 字符串 节点 acwing

Trie树 学习感受

相比于之前学习的kmp匹配算法,Trie树的实现还是非常好理解的。(kmp算法太难了orz)

从直观的模拟过程来看,trie树就像一颗树一样,从上(根节点)到下(叶节点)有序串联起来组成一个字符串。

每一个额外标记结束的位置表示字符串的结束,通过计算标记数即可指导一共有多少该字符串。

 

 

从暴力算法看Trie算法

先想想,如果要是暴力算法来做的话,应该怎么去统计字符串出现次数呢?

首先要利用数组去存储各种不相同的字符串,在读入一个新的字符串时,需要先判断他和已有的字符串是否相等,如果不相等,则将该字符串存入,如果相等,则跳过该字符串。显然,暴力算法的时间复杂度会很大。在这里,有没有更好的判断方法,让我不用再去每次判断都要遍历所有已经储存的字符串呢?

我们来着重讨论判断他和已有字符串是否相等,在这里的判断方法显然是循环遍历两个字符串,判断字符串长度以及每个位置是否相等。那么,在循环遍历所有字符串的过程中,不难发现,对于部分相等以及完全相等字符串,从字符串第一个字符起,总会和目标字符串有一个公共部分。那么,我们是否可以对于字符串每一个位置(对于数的每一层)只存储一个字符串该位置出现的字符,使得所有字符串共用一颗树(如上图)。这样在大大减少时间复杂度的同时,空间复杂度也得到的减小。

Trie树的实现

Trie树的实现过程是用数组模拟实现多叉树的过程。首先需要一个二维数组 trie[n][m] 来实现树。其中 n 代表所有字符的总长度,m代表多叉树的最大分支。

再者,需要一个 cnt[n] 数组存储每个字符串出现的次数,n应该小于所有字符的总数量。

最后,需要一个整型变量 idx , 用于存储树中某个节点对应 cnt 数组的下标。

 

树的插入代码如下:

void insert(string s)
{
    int tmp = 0;//tmp 代表当前节点的位置,0 代表根节点 
    for(auto c : s)
    {
        int u = c - 'a';//将二十六个字母映射到0到25
        if(!trie[tmp][u]) trie[tmp][u] = ++ idx;//如果字典树当前位置当中没有这个字符,则建立这个字符,且将他与cnt数组对应
        tmp = trie[tmp][u];//类比指针,指向字典树下一个位置
    }
    cnt[tmp] ++;//把字符串结束对应的点的计数数组增加一
}

树的查询代码如下:

int search(string s)
{
    int tmp = 0;//tmp 代表当前节点的位置,0 代表根节点 
    for(auto c : s)
    {
        int u = c - 'a';//将二十六个字母映射到0到25
        if(!trie[tmp][u]) return 0;//如果字典树当前位置当中没有这个字符,则查询结束,证明没有这个字符串
        else tmp = trie[tmp][u];//类比指针,指向字典树下一个位置
    }
    return cnt[tmp];//返回该字符串的个数
}

 

标签:tmp,Trie,trie,int,字符串,节点,acwing
From: https://www.cnblogs.com/y0sh1no/p/17462096.html

相关文章

  • 【每日一题】LeetCode 859. 亲密字符串
    题目描述给你两个字符串s和goal,只要我们可以通过交换s中的两个字母得到与goal相等的结果,就返回true;否则返回false。交换字母的定义是:取两个下标i和j(下标从0开始)且满足i!=j,接着交换s[i]和s[j]处的字符。例如,在“abcd”中交换下标0和下标2的元素可以......
  • 【每日一题】LeetCode 438.找到字符串中所有字母异位词
    题目给定两个字符串s和p,找到s中所有p的异位词的子串,返回这些子串的起始索引。不考虑答案输出的顺序。异位词指由相同字母重排列形成的字符串(包括相同的字符串)。输入:s=“cbaebabacd”,p=“abc”输出:[0,6]解释:起始索引等于0的子串是“cba”,它是“abc”......
  • 【每日一题】AcWing 1904. 奶牛慢跑
    题目奶牛们又出去锻炼蹄子去了!有N头奶牛在无限长的单行道上慢跑。每头奶牛在跑道上开始奔跑的位置互不相同,一些奶牛的奔跑速度可能相同,也可能不同。由于跑道是单行道,十分狭窄,奶牛们无法相互超越。当一头速度很快的牛追上另一头牛时,她必须减速至与另一头牛速度相同以免发生碰撞,并成......
  • LeetCode 1790.仅执行一次字符串交换能否使两个字符串相等
    LeetCode1790.仅执行一次字符串交换能否使两个字符串相等思路暴力模拟,根据题目思路直接写代码即可,依次遍历字符串的每一位,如果相等则继续,如果不相同则分别储存在记录量flag1,flag2中,如果不同的位置超过两个或者只有一个则返回false,如果不存在不同位置或者不同的位置相同就返回tru......
  • LeetCode 481.神奇字符串
    LeetCode481.神奇字符串本题目应该说难在读题,根据题目描述的意思,s作为一个神奇字符串,他的每一组数都是根据前面的数去判定的,以开头的122之后为例,122之的末尾为2,而s的规则是1和2交替出现,所以后面应当跟着"1",而这一组"1"的数量则由其前面的"2"来决定,所以这一组有两个"1",同理,在这后面......
  • 006 数据库学习笔记--字符串操作函数 + 索引
    常用字符串操作函数:--返回字符串中指定的子串出现的开始位置(索引从1开始)selectCHARINDEX('34','1234567890123')asstartIndex--返回字符串中指定的子串出现的开始位置(索引从1开始,字串前必须加%)selectPATINDEX('%34%','1234567890123')asstartIndex--大小写转化s......
  • 8、hive的关系运算、逻辑预算、数学运算、数值运算、日期函数、条件函数和字符串函数
    ApacheHive系列文章1、apache-hive-3.1.2简介及部署(三种部署方式-内嵌模式、本地模式和远程模式)及验证详解2、hive相关概念详解--架构、读写文件机制、数据存储3、hive的使用示例详解-建表、数据类型详解、内部外部表、分区表、分桶表4、hive的使用示例详解-事务表、视图、物......
  • Python如何使用函数进行字符串大小写转换?
    在Python语言中,为了方便开发者对字符串中的字母进行大小写转换,为大家提供了3种函数,它们分别是title()、lower()和upper(),那么该如何使用这些函数呢?以下是详细的内容:1、title()方法title()方法用于将字符串中每个单词的首字母转为大写,其他字母全部转为小写,转换完成......
  • 7.16 字符串格式化
    formatpublicclassHelloWorld{publicstaticvoidmain(Stringargs[]){Stringname="张三";intage=19;doublescore=8.8;Stringstr=String.format("姓名:%s,年龄:%d,成绩:%5.2f",name,age,score);......
  • 7.15 字符串的截取
    substring,经常结合indexOf,lastIndexOf使用,Stringstr="www.mldn.cn";System.out.println(str.substring(4));//4之后都截取System.out.println(str.substring(4,8));//截取4-8,和php不同,后面的参数不是截取的长度;......