我们常常用Trie(也叫前缀树)来保存字符串集合。如下图所示就是一个Trie。

上图表示的字符串集合为$\{a,to,tea,ted,ten,i,in,inn \}$,每个单词的结束位置对应一个“单词结点”。反过来,从根节点到每个单词结点的路径上的所有字母(不是结点上的字母)连接而成的字符串就是该结点对应的字符串。在程序上,将根节点编号为0,然后把其余结点编号为从1开始的正整数,然后用一个数组来保存每个结点的所有子节点,用下标直接存取。

具体来说,可以用$ch[i][j]$保存结点$i$的那个编号为$j$的子结点。为什么叫“编号为$j$呢?”比如,若是处理全部由小写字母组成的字符串,把所有小写字母按照字典序编号为0,1,2,...,则$ch[i][0]$表示结点$i$的子结点$a$。如果这个子结点不存在,则$ch[i][0]=0$。用sigma_size表示字符集的大小,比如,当字符集为全体小写字母时,sigma_szie=26。

使用Trie的时候,往往需要在单词结点上附加信息,其中$val[i]$表示结点$i$对应的附加信息。例如,如果每个字符串有一个权值,就可以把这个权值保存在$val[i]$中。简单起见,下面的额代码假定权值大于0,因此$val[i]>0$当且仅当结点$i$是单词结点(即val为0表示中间结点)。

Trie的定义、插入和查找的代码:

struct Trie
{
int ch[maxnode][sigma_size];
int val[maxnode];
int sz;
void clear(){ sz = ; memset(ch[], , sizeof(ch[])); } int idx(char c) { return c - 'a'; } //字符c的编号 //插入字符串s,附加信息为v。注意v必需非0,因为0代表"本结点不是单词结点"
void insert(const char *s, int v)
{
int u = , n = strlen(s);
for (int i = ; i < n; i++)
{
int c = idx(s[i]);
if (!ch[u][c])
{
memset(ch[sz], , sizeof(ch[sz]));
val[sz] = ; //中间结点的附加信息为0
ch[u][c] = sz++; //新建结点
}
u = ch[u][c]; //往下走
}
val[u] = v; //字符串的最后一个字符的附加信息为v
} //找字符串s的长度不超过len的前缀
void find(const char* s, int len, vector<int>& ans)
{
int u = ;
for (int i = ; i < len; i++)
{
if (s[i] == '\0') break;
int c = idx(s[i]);
if (!ch[u][c]) break;
u = ch[u][c]; //往下走
if (val[u] != ) ans.push_back(val[u]); //找到一个前缀
}
}
};

Trie入门讲解的更多相关文章

  1. poj1056 (Trie入门)寻找字符串前缀

    题意:给你一堆字符串,问是否满足对于任意两个字符串a.b,a不是b的前缀 字典树==前缀树==Trie树 trie入门题,只用到了insert和query操作 #include <cstdio& ...

  2. Mysql C语言API编程入门讲解

    原文:Mysql C语言API编程入门讲解 软件开发中我们经常要访问数据库,存取数据,之前已经有网友提出让鸡啄米讲讲数据库编程的知识,本文就详细讲解如何使用Mysql的C语言API进行数据库编程.   ...

  3. #001 CSS快速入门讲解

    CSS入门讲解 HTML人+CSS衣服+JS动作=>DHTML CSS: 层叠样式表 CSS2.0 和 CSS3.0 版本,目前学习CSS2, CSS3只是多了一些样式出来而已 CSS 干啥用的 ...

  4. HTML5游戏开发引擎Pixi.js新手入门讲解

    在线演示 本地下载 ​这篇文章中,介绍HTML5游戏引擎pixi.js的基本使用. 相关代码如下: Javascript 导入类库:(使用极客的cdn服务:http://cdn.gbtags.com) ...

  5. AngularJS入门讲解4:多视图,事件绑定,$resource服务讲解

    上一课,大家知道,手机详细模板我们没有写出来,使用的是一个占位模板. 这一课,我们先实现手机详细信息视图,这个视图会在用户点击手机列表中的一部手机时被显示出来. 为了实现手机详细信息视图,我们将会使用 ...

  6. poj2104 k-th number 主席树入门讲解

    poj2104 k-th number 主席树入门讲解 定义:主席树是一种可持久化的线段树 又叫函数式线段树   刚开始学是不是觉得很蒙逼啊 其实我也是 主席树说简单了 就是 保留你每一步操作完成之后 ...

  7. #001 HTML快速入门讲解

    整理了下最早开始学习技术的笔记  3W1H学习法? (其他技术同理) What   HTML是什么? When  什么时候使用HTML? Why    为什么使用HTMl? HOW  怎么使用HTML ...

  8. 原生AJAX入门讲解(含实例)

    相对于jQuery.YUI以及其他一些类库的AJAX封装,原生JS的AJAX显得那么的尴尬,兼容性不好,要记很多的方法属性,调用不便捷,代码臃肿...但我还是想说,原生JS才是最根本最底层的知识(虽然 ...

  9. hadoop中HBase子项目入门讲解

    HBase 是Hadoop的一个子项目,HBase采用了Google BigTable的稀疏的,面向列的数据库实现方式的理论,建立在hadoop的hdfs上,一方面里用了hdfs的高可靠性和可伸缩行, ...

随机推荐

  1. Infoapth 使用拼写 并加载web part 在Infopath的页面上

    <g_vml_:shape style="POSITION: absolute; WIDTH: 568px; HEIGHT: 1312px; TOP: 0px; LEFT: 0px&q ...

  2. Celery 基本使用

    1. 认识 Celery Celery 是一个 基于 Python 开发的分布式异步消息任务队列,可以实现任务异步处理,制定定时任务等. 异步消息队列:执行异步任务时,会返回一个任务 ID 给你,过一 ...

  3. 洛谷 - P2324 - 骑士精神 - A*搜索

    为什么估价是16,因为最后一步复原空格可以恢复两个位置,当然设成17.18都可以. #include<bits/stdc++.h> using namespace std; typedef ...

  4. Python中生成随机数

    目录 1. random模块 1.1 设置随机种子 1.2 random模块中的方法 1.3 使用:生成整形随机数 1.3 使用:生成序列随机数 1.4 使用:生成随机实值分布 2. numpy.ra ...

  5. Unity ShaderLab 光照随笔

    unity camera默认3种渲染路径,unity5.50里面有4种 camera Rendering Path 1 vertexLit(逐顶点,一般在vert中处理)  2 forward (前向 ...

  6. 洛谷P1005 矩阵取数游戏

    P1005 矩阵取数游戏 题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次 ...

  7. python 之 列表生成式、生成器表达式、模块导入

    5.16 列表生成式 l=[]for i in range(100):    l.append('egg%s' %i)print(l)​l=['egg%s' %i for i in range(100 ...

  8. 00 | Two Sum

    Question Given an array of integers, return indices of the two numbers such that they add up to a sp ...

  9. String,StringBuffer和StringBuilder

    String,StringBuffer和StringBuilder分别应该在什么情况下使用? String 是Java的字符串类,其实质上也是用Char类型存储的,但是除了hash属性,其他的属性都声 ...

  10. php追加数组的问题

    PHP数组合并两种方法及区别 如果是关联数组,如下: 代码如下: $a = array( 'where' => 'uid=1', 'order' => 'uid', ); $b = arr ...