字典树模板
老久没写博客了,跟一波风。
去年暑假集训的时候学的字典树,ac自动机什么的,用的不是很多,该忘还是得忘,毕竟属于数据结构(我也想全面developing啊),我专精的图论有空再发嘛
寒假集训开始,打算先复习一下以前学的各种算法,然后再去专研图论的东西(学了一堆,脑子里面却已经忘得零零散散,再去学新东西着实顶不住那零散的阴影)
还好,当初学的很认真,现在简单回想复习一下,懂还是没问题的,内化为自己的理解。
示例模板题:http://www.fjutacm.com/Problem.jsp?pid=2050
自己的理解融于代码之中了,另外也推荐一篇别人写的(我就是馋人家的好图懒得搬):https://blog.csdn.net/weixin_39778570/article/details/81990417

#include<cstdio> #include<cstring> #define N 100009 #define mt(x) memset(x,0,sizeof x) char s[N][30],S[30];//存字符串 int tree[N*5][30];//字典树 int index[N*5],num,cnt;//下标辅助 /* index用于 指出根节点所示的字符串 在s字符串数组中的下标 cnt 用于辅组index依序储存根节点 num 用于指向在tree中新的根节点所示值 也就是说: 创建tree时,根节点对应++num去标记, 完整字符串对应index中cnt去标记 (也就是在index数组中,特定的num值转存下标为++cnt,表示这里是第cnt+1个字符串) 然后,要在s字符串数组中找指定字符串 首先,查找完整字符串的cnt下标,也就是num的值,原字符串遍历找到对应num 得到num之后,我们已经用index数组标记了num所示的字符串在s字符串数组中的下标为cnt 也即, s[index[num]],就是我们要找的字符串 */ void Init() { mt(tree);mt(s);mt(index); num=0;cnt=0; } void Insert() { int t=0;//根结点值 int i=0,k=0;//区分两字符串 while(S[i++]!=' '); k=i;//标记区分下标,k指向value字符串第一个字符 while(S[i]) { int id=S[i++]-'a'; if(!tree[t][id])tree[t][id]=++num;//不存在,则创建分支,标记为++num t=tree[t][id];//转移结点 } index[t]=++cnt; strncpy(s[cnt],S,k-1);//复制字符串 /* for(int i=0;i<k-1;++i) s[cnt][i]=S[i]; //*/ } int Find() { int t=0,i=0; while(S[i]) { int id=S[i++]-'a'; if(!tree[t][id])return 0; t=tree[t][id]; } return t; } int main() { Init(); while(gets(S)&&S[0]) Insert(); while(~scanf("%s",S)) { int i=Find(); printf("%s\n",i?s[index[i]]:"eh"); } return 0; }
另外,因为是两两匹配,很容易让人想到STL里的一个关联容器Map,在题目数据很水或者时限不小的情况也可以这么写,这题也行。
(两种的解法时间是倍数关系,字典树tql)

#include<iostream> #include<cstdio> #include<map> using namespace std; int main() { map<string,string>p; char x[30],y[30]; while(gets(x)&&x[0]) { sscanf(x,"%s%s",y,x); p[x]=y; } while(gets(x)) cout<<(p[x]==""?"eh":p[x])<<endl; return 0; }
另外,复习的时候想到了,通过另外一个数组来标识一个数组的下标这种写法很常见,类似索引的意思
最经典的就是链式前向星存图,里面的head数组与num搭配,指定边的下标
好处的话,能理解桶排的妙处都能理解这样写的好处吧,字典树这里面也用到了,将字典树里的结点值存在一个自增数组里,再用自增值取指向结果字符串数组中的下标
也就这么个转换关系,初次理解可能会觉得有点绕,但真的不难,也就【x->三元关系->y】这种意思。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!