Trie树(字典树)算法模版

算法介绍

Trie树又叫字典树或者说前缀树
高效的存储和查找字符串集合的算法结构
主要有2种操作,存储字符串,查询字符串

在这里插入图片描述

模版题

在这里插入图片描述
在这里插入图片描述

主要思路分析

模版中主要有两个函数query函数和insert函数
其本质都是找字符串最后一个元素的编号idx

insert函数:如果没有该结点,就可以创建出,记录字符串最后一个元素的编号idx,用p 存储
在cnt[N]数组中,++,(cnt[idx]++)统计字符串出现的数量
query函数,找到字符串最后一个元素的编号idx,用p存储,然后通过cnt数组,可以得到该字符串出现的次数(cnt[p])

代码

#include<iostream>
#include<cstdio>

using namespace std;

const int N = 1e5 + 10;

int son[N][26];

//字符串都是有小写字母组成,所以一个点,最多有26个子结点
//二维数组的行的范围是字符串大小的范围
//0表示根结点,为NULL, 如果该结点不存在,也是0

int cnt[N]; 
//存储的每个字符串,最后一个元素出现的次数-->该字符串出现的次数
int idx;
//每个结点都有独一唯一的idx

char str[N]; //字符串

void insert(char * str)
{
    int p = 0;  
    //记录每个字符串的末尾元素-->记录该结点的idx
    //也是二维数组的行
    
    //字符串以 "/0" 结尾,可用做循环条件
    for(int i = 0; str[i]; i++)
    {
        //以ASCII码记录  0~ 25
        int u = str[i] - 'a';
        //不存在这个结点,插入 (赋予结点唯一的idx)
        if(!son[p][u])  son[p][u] = ++idx;
        p = son[p][u];
        
        //注意:这里不能用if else 语句,在做插入的时候,如果不存在,就插入新结点,更新下idx,要记录元素的idx
        //存在,说明该结点不用插入,但还是要记录该结点的idx,区别于查询操作(可用if else 语句,就找到,找不到两种情况),当然查询操作也可不用
        
    }

    //记录该字符串出现的次数
    cnt[p]++;
}

int query(char *str)
{
    int p = 0;
        
    for(int i = 0; str[i]; i++)
    {
        int u = str[i] - 'a';
    //该结点不存在,找不到,返回0  
        if(!son[p][u])  return 0;
        p = son[p][u];  //记录下一个元素的idx
    }
    
    //循环结束,找到字符串尾元素的idx
    
    return cnt[p];
}


int main()
{
    int n;
    scanf("%d", &n);
    
    while(n--)
    {
        char op[2];
        scanf("%s%s", op, str);
        
        if( *op == 'I') insert(str);
        else    printf("%d\n", query(str));
        
    }
    
    return 0;
}



  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

温柔了岁月.c

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值