- 浏览: 99330 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
sulanyan29:
您 好,请问下android程序中调用以下两个命令,开启: s ...
linux 防火墙启动、添加规则 -
rainliu:
Can use jrockit monitor for IBM ...
java堆栈溢出 JRockit+Tomcat 实战调试
在一个三叉搜索树(Ternary Search Trie)中,每一个节点包括一个字符,但和数字搜索树不同,三叉搜索树只有三个指针:一个指向左边的树;一个指向右边的树;还有一个向下,指向单词的下一个数据单元。三叉搜索树是二叉搜索树和数字搜索树的混合体。它有和数字搜索树差不多的速度但是和二叉搜索树一样只需要相对较少的内存空间。
树是否平衡取决于单词的读入顺序。如果按排序后的顺序插入,则生成方式最不平衡。单词的读入顺序对于创建平衡的三叉搜索树很重要,但对于二叉搜索树就不太重要。通过选择一个排序后数据单元集合的中间值,并把它作为开始节点,我们可以创建一个平衡的三叉树。可以写一个专门的过程来生成平衡的三叉树词典。
取得平衡的单词排序类似于洗扑克牌。假想有若干张扑克牌,每张牌对应一个单词,先把牌排好序,然后取最中间的一张牌,单独放着。剩下的牌分成了两摞,左边一摞牌中也取最中间的一张放在取出来的那张牌后面。右边一摞牌中也取最中间的一张放在取出来的牌后面,以此类推。
我们再次以有序的数据单元(as at be by he in is it of on or to)为例。 首先我们把关键字"is"作为中间值并且构建一个包含字母"i"的根节点。它的直接后继节点包含字母"s"并且可以存储任何与"is"有关联的数据。对于"i"的左树,我们选择"be"作为中间值并且创建一个包含字母"b"的节点,字母"b"的直接后继节点包含"e"。该数据存储在"e"节点。对于"i"的右树,按照逻辑,选择"on"作为中间值,并且创建"o"节点以及它的直接后继节点"n"。
TernarySearchTrie本身存储关键字到值的对应关系,可以当做HashMap对象来使用。关键字按照字符拆分成许多节点,以TSTNode的实例存在。值存储在TSTNode的data属性中。TSTNode的实现代码如下所示:
查找词典的基本过程是:输入一个词,返回这个词对应的TSTNode对象,如果该词不在词典中则返回空。在查找词典的过程中,从树的根节点匹配Key,按Char从前往后匹配Key。charIndex表示Key当前要比较的Char的位置。匹配过程如下所示:
三叉树的创建过程也就是在Trie树上创建和单词对应的节点。实现代码如下所示:
相对于查找过程,创建过程在搜索过程中判断出链接的空值后创建相关的节点,而不是碰到空值后结束搜索过程并返回空值。
同一个词可以有不同的词性,例如"朝阳"既可能是一个"区",也可能是一个"市"。可以把这些和某个词的词性相关的信息放在同一个链表中。这个链表可以存储在TSTNode 的Data属性中。
树是否平衡取决于单词的读入顺序。如果按排序后的顺序插入,则生成方式最不平衡。单词的读入顺序对于创建平衡的三叉搜索树很重要,但对于二叉搜索树就不太重要。通过选择一个排序后数据单元集合的中间值,并把它作为开始节点,我们可以创建一个平衡的三叉树。可以写一个专门的过程来生成平衡的三叉树词典。
/** * 在调用此方法前,先把词典数组k排好序 * @param fp 写入的平衡序的词典 * @param k 排好序的词典数组 * @param offset 偏移量 * @param n 长度 * @throws Exception */ void outputBalanced(BufferedWriter fp,ArrayList<String> k,int offset, int n){ int m; if (n < 1) { return; } m = n >> 1; //m=n/2 String item= k.get(m + offset); fp.write(item);//把词条写入到文件 fp.write('\n'); outputBalanced(fp,k,offset, m); //输出左半部分 outputBalanced(fp,k, offset + m + 1, n - m - 1); //输出右半部分 }
取得平衡的单词排序类似于洗扑克牌。假想有若干张扑克牌,每张牌对应一个单词,先把牌排好序,然后取最中间的一张牌,单独放着。剩下的牌分成了两摞,左边一摞牌中也取最中间的一张放在取出来的那张牌后面。右边一摞牌中也取最中间的一张放在取出来的牌后面,以此类推。
我们再次以有序的数据单元(as at be by he in is it of on or to)为例。 首先我们把关键字"is"作为中间值并且构建一个包含字母"i"的根节点。它的直接后继节点包含字母"s"并且可以存储任何与"is"有关联的数据。对于"i"的左树,我们选择"be"作为中间值并且创建一个包含字母"b"的节点,字母"b"的直接后继节点包含"e"。该数据存储在"e"节点。对于"i"的右树,按照逻辑,选择"on"作为中间值,并且创建"o"节点以及它的直接后继节点"n"。
TernarySearchTrie本身存储关键字到值的对应关系,可以当做HashMap对象来使用。关键字按照字符拆分成许多节点,以TSTNode的实例存在。值存储在TSTNode的data属性中。TSTNode的实现代码如下所示:
public final class TSTNode { /** 节点的值 */ public Data data=null;// data属性可以存储 词原文和词性、词频等相关的信息 protected TSTNode loNode; //左边节点 protected TSTNode eqNode; //中间节点 protected TSTNode hiNode; //右边节点 protected char splitchar; // 本节点表示的字符 /** * 构造方法 * *@param splitchar 该节点表示的字符 */ protected TSTNode(char splitchar) { this.splitchar = splitchar; } public String toString() { return "splitchar:"+ splitchar; } }
查找词典的基本过程是:输入一个词,返回这个词对应的TSTNode对象,如果该词不在词典中则返回空。在查找词典的过程中,从树的根节点匹配Key,按Char从前往后匹配Key。charIndex表示Key当前要比较的Char的位置。匹配过程如下所示:
protected TSTNode getNode(String key, TSTNode startNode) { if (key == null ) { return null; } int len = key.length(); if (len ==0) return null; TSTNode currentNode = startNode; //匹配过程中当前节点的位置 int charIndex = 0; char cmpChar = key.charAt(charIndex); int charComp; while (true) { if (currentNode == null) {//没找到 return null; } charComp = cmpChar - currentNode.splitchar; if (charComp == 0) {//相等 charIndex++; if (charIndex == len) {//找到了 return currentNode; } else { cmpChar = key.charAt(charIndex); } currentNodecurrentNode = currentNode.eqNode; } else if (charComp < 0) {//小于 currentNodecurrentNode = currentNode.loNode; } else {//大于 currentNodecurrentNode = currentNode.hiNode; } } }
三叉树的创建过程也就是在Trie树上创建和单词对应的节点。实现代码如下所示:
//向词典树中加入一个单词的过程 private TSTNode addWord(String key) { TSTNode currentNode = root; //从树的根节点开始查找 int charIndex = 0; //从词的开头匹配 while (true) { //比较词的当前字符与节点的当前字符 int charComp =key.charAt(charIndex) - currentNode.splitchar; if (charComp == 0) {//相等 charIndex++; if (charIndex == key.length()) { return currentNode; } if (currentNode.eqNode == null) { currentNode.eqNode = new TSTNode(key.charAt (charIndex)); } currentNodecurrentNode = currentNode.eqNode; } else if (charComp < 0) {//小于 if (currentNode.loNode == null) { currentNode.loNode = new TSTNode(key.charAt (charIndex)); } currentNodecurrentNode = currentNode.loNode; } else {//大于 if (currentNode.hiNode == null) { currentNode.hiNode = new TSTNode(key.charAt (charIndex)); } currentNodecurrentNode = currentNode.hiNode; } } }
相对于查找过程,创建过程在搜索过程中判断出链接的空值后创建相关的节点,而不是碰到空值后结束搜索过程并返回空值。
同一个词可以有不同的词性,例如"朝阳"既可能是一个"区",也可能是一个"市"。可以把这些和某个词的词性相关的信息放在同一个链表中。这个链表可以存储在TSTNode 的Data属性中。
发表评论
-
微信群消息自动转发另一群
2017-09-04 18:46 11683周六,咱们小区业委会的秘书长娟姐找到我,说小区业主太多,一个群 ... -
java堆栈溢出 JRockit+Tomcat 实战调试
2012-07-24 10:19 27991. JRockit简介 Jrockit是Bea开发的符合J ... -
java.lang.OutOfMemoryError: unable to create new native thread
2012-02-12 16:09 3603今天系统突然收到错误日志: Feb 12, 2012 1:28 ... -
Lucene 分词解读(二)--Analyzer
2011-09-19 17:33 1380Lucene中的Analyzer 为了更好地搜索中文,在Lu ... -
Lucene写自己的Analyzer
2011-09-19 17:32 1473实现一个简单的分析器(Analyzer)的例子如下所示:] ... -
Lucene 分词解读(一)
2011-09-19 17:31 1018Lucene中的中文分词 Lucene中处理中文的常用方法有 ... -
三叉Trie树
2011-09-13 16:20 6在一个三叉搜索树(Tern ... -
Lucene写自己的Analyzer
2011-09-13 15:57 44实现一个简单的分析器(Analyzer)的例子如下所示:] ... -
Lucene 分词解读(二)--Analyzer
2011-09-13 15:51 9Lucene中的Analyzer 为了更好地搜索中文,在Lu ... -
Lucene 分词解读(一)
2011-09-13 15:46 1010Lucene中的中文分词 Lucene中处理中文的常用方法有 ... -
大并发搜索下关键词前缀匹配值得考虑的一种数据结构---Trie
2011-09-12 23:43 2350如果要实现一个能支撑 ... -
大并发搜索下值得考虑的一种数据结构---Trie
2011-09-12 23:42 0如果要实现一个能支撑大数据量并发搜索的引擎,一般不会采用luc ... -
nginx 301 重定向 包括域名、目录、文件等方法 (二)
2011-09-09 14:24 10609nginx rewrite 伪静态配置参数详细说明 正则表达 ... -
nginx 301 重定向 包括域名、目录、文件等方法 (一)
2011-09-09 14:15 1473在网站建设中需要网页 ... -
查看Oracle表空间大小的方法
2011-09-08 10:16 859Oracle表空间大小的查看方法应该是我们都需要掌握的知识,下 ... -
[推荐] java生成csv文件
2011-08-15 10:08 1332import java.io.File; import ...
相关推荐
对于一般的Trie树的数据结构,它的实现简单但是空间效率极低。三叉搜索树使用了一种聪明的手段去解决字典树的内存问题(空的指针数组)。为了避免多余的指针占用内存,每个节点不再用数组来表示,而是表示成“树中有...
三叉树,又称为Trie或Prefix Tree,是一种有序树数据结构,它能有效存储和查找具有公共前缀的字符串。与二叉搜索树不同,三叉树每个节点通常有三个子节点,分别代表字符集中的三个不同字符。这样的设计使得三叉树在...
- **查找词典算法**:包括标准Trie树和三叉Trie树的算法。 - **中文分词的原理与流程**:解释了全切分词图的保存和形成,以及基于概率语言模型和N元分词方法的分词技术。 - **语料库与新词发现**:讨论了如何建立...
- **4.2.2 三叉Trie树**:介绍了三叉Trie树的特点及其优势。 - **4.3 中文分词的原理**:详细介绍了中文分词的基本原理和技术背景。 - **4.4 中文分词流程与结构**:讲解了中文分词的一般流程及结构设计。 - **4.5 ...
它基于有限状态自动机(FSA)的概念,通过构建一种特殊的自动机——三叉搜索树(Ternary Search Trie,TST),来实现对大量模式串的并行查找。在AC自动机中,每个节点不仅包含当前字符的信息,还存储了前缀指向的...
这些算法结合了快速排序(Quicksort)与基数排序(Radix Sort)、Trie 树与二叉搜索树(Binary Search Tree),不仅在理论上具有优越性,在实际应用中也表现出色。 #### 一、理论背景 ##### 1.1 快速排序 快速...
三元搜索树是trie的一种类型(有时称为前缀树),其中将节点排列在其中一种类似于二叉搜索树的方式,但是最多具有三个子级,而不是二叉树的限制,与其他前缀树一样,三叉搜索树可以用作关联映射结构,并具有增量字符...
a.10 个数据结构:数组,链表,栈,队列,散列表,三叉树,堆,跳表图,Trie 树。 b.10 个算法:递归,排序,二分查找,搜索,哈希算法,贪心算法,分治算法,回溯算法,动态规划,字符串匹配算法。 四。学习技巧 ...
系统还可能包含搜索功能,这可能涉及到模糊匹配和排序算法,如Trie树(字典树)用于快速查找类似姓名,或者快速排序和归并排序用于对学友信息进行排序。 最后,为了便于用户界面的交互,可能还会涉及到数据库技术,...
范例1-100 按关键字符串遍历Trie树 301 ∷相关函数:SearchTrie函数 1.6.8 哈希表的基本操作 306 范例1-101 哈希表的基本操作 306 ∷相关函数:SearchHash函数 1.7 图 311 1.7.1 图的邻接矩阵存储表示 311 范例1-102...
范例1-100 按关键字符串遍历Trie树 301 ∷相关函数:SearchTrie函数 1.6.8 哈希表的基本操作 306 范例1-101 哈希表的基本操作 306 ∷相关函数:SearchHash函数 1.7 图 311 1.7.1 图的邻接矩阵存储表示 311 范例1-102...
范例1-100 按关键字符串遍历Trie树 301 ∷相关函数:SearchTrie函数 1.6.8 哈希表的基本操作 306 范例1-101 哈希表的基本操作 306 ∷相关函数:SearchHash函数 1.7 图 311 1.7.1 图的邻接矩阵存储表示 311 范例1-102...
范例1-100 按关键字符串遍历Trie树 301 ∷相关函数:SearchTrie函数 1.6.8 哈希表的基本操作 306 范例1-101 哈希表的基本操作 306 ∷相关函数:SearchHash函数 1.7 图 311 1.7.1 图的邻接矩阵存储表示 311 范例1-102...
对于字符串匹配,Nginx采用了一种高效的三叉字符串排序树(Trie树)结构,以快速找到最匹配的`location`。这种数据结构在构建时就考虑到了平衡性,从而确保了高效查找。 字符串匹配的`location`类型有以下几种: 1...
Nginx为了提高匹配效率,对字符串匹配的`location`采用了三叉字符串排序树(Trie树)的数据结构。这种方式使得搜索效率更高,尤其是在大量`location`配置的情况下。 为了更好地理解和应用这些规则,以下是一些实用...
范例1-100 按关键字符串遍历Trie树 301 ∷相关函数:SearchTrie函数 1.6.8 哈希表的基本操作 306 范例1-101 哈希表的基本操作 306 ∷相关函数:SearchHash函数 1.7 图 311 1.7.1 图的邻接矩阵存储表示 311 ...
范例1-100 按关键字符串遍历Trie树 301 ∷相关函数:SearchTrie函数 1.6.8 哈希表的基本操作 306 范例1-101 哈希表的基本操作 306 ∷相关函数:SearchHash函数 1.7 图 311 1.7.1 图的邻接矩阵存储表示 311 ...
范例1-100 按关键字符串遍历Trie树 301 ∷相关函数:SearchTrie函数 1.6.8 哈希表的基本操作 306 范例1-101 哈希表的基本操作 306 ∷相关函数:SearchHash函数 1.7 图 311 1.7.1 图的邻接矩阵存储表示 311 ...