Trie tree实践
1、Trie树
Trie树即字典树或前缀树,
2、实践
代码实践如下:
package cn.edu.buaa.trie; import java.util.HashSet; /**
* @author zsm
* @date 2016年10月25日 上午11:03:13
* @version 1.0
* @parameter
* @return
*/
public class Trie {
private TrieNode trieRoot;
private int treeSize; public Trie() {
trieRoot = new TrieNode();
treeSize = 0;
} public TrieNode getRoot() {
return trieRoot;
} public int getTreeSize() {
return treeSize;
} /**
* 添加单词
*/
public void addWord(String word, int wordId) {
addWord(trieRoot, word, wordId);
} public void addWord(TrieNode root, String word, int wordId) {
// 输入单词为空
if (null == word || word.length() == 0) {
return;
} // 确定第一个字符在放在哪个孩子节点中
int k = TrieNode.getCharPosition(word.charAt(0)); // 该孩子为空,初始化
if (root.childNodes[k] == null) {
root.childNodes[k] = new TrieNode();
treeSize++;
root.childNodes[k].nodeChar = word.charAt(0);
}
// 单词出现在该孩子节点中
root.childNodes[k].wordSet.add(wordId); word = word.substring(1);
// 说明是最后一个字符,该词词频数加1
if (word.length() == 0) {
root.childNodes[k].freq++;
} else {
addWord(root.childNodes[k], word, wordId);
}
} /**
* 删除单词
*/
public void deleteWord(String word, int wordId) {
deleteWord(trieRoot, word, wordId);
} enum DELETERES {
FAIL_EMPTYWORLD, FAIL_WORLD_NOT_EXIST, SUCCESS
}; public DELETERES deleteWord(TrieNode root, String word, int wordId) {
// 输入单词为空
if (null == word || word.length() == 0) {
return DELETERES.FAIL_EMPTYWORLD;
} int k = TrieNode.getCharPosition(word.charAt(0)); // 第一个字符不在树中,说明没有要删除的单词
if (root.childNodes[k] == null) {
return DELETERES.FAIL_WORLD_NOT_EXIST;
} // 第一个字符在树中
DELETERES res;
{
word = word.substring(1);
// 找到该单词
if (word.length() == 0 && root.childNodes[k].freq > 0) {
root.childNodes[k].freq--;
res = DELETERES.SUCCESS;
} else {
res = deleteWord(root.childNodes[k], word, wordId);
} if (res == DELETERES.SUCCESS) {
// 从沿途节点移除该单词
root.childNodes[k].wordSet.remove(wordId);
// 没单词了,释放节点
if (root.childNodes[k].wordSet.size() == 0) {
root.childNodes[k] = null;
treeSize--;
}
}
return res;
}
} /**
* 修改单词
*/
public void updateWord(String newWord, String oldWord, int wordId) {
updateWord(trieRoot, newWord, oldWord, wordId);
} public void updateWord(TrieNode root, String newWord, String oldWord, int wordId) {
if (deleteWord(root, oldWord, wordId) == DELETERES.SUCCESS) {
addWord(root, newWord, wordId);
}
} /**
* 找以给定单词为前缀的所有单词的id
*/
public HashSet<Integer> searchPrefixWord(String word) {
return searchPrefixWord(trieRoot, word);
} public HashSet<Integer> searchPrefixWord(TrieNode root, String word) { HashSet<Integer> wordSet = new HashSet<Integer>(); // 输入单词为空
if (null == word || word.length() == 0) {
return wordSet;
} int k = TrieNode.getCharPosition(word.charAt(0));
// 单词里某个字符在树种不存在,说明没有该单词
if (root.childNodes[k] == null) {
return wordSet;
} word = word.substring(1); if (word.length() == 0) {
wordSet = root.childNodes[k].wordSet;
} else {
wordSet = searchPrefixWord(root.childNodes[k], word);
}
return wordSet;
} /**
* 统计给定单词出现的次数
*/
public int wordCount(String word) {
return wordCount(trieRoot, word);
} public int wordCount(TrieNode root, String word) { // 输入单词为空
if (null == word || word.length() == 0) {
return 0;
} int k = TrieNode.getCharPosition(word.charAt(0));
// 单词里某个字符在树种不存在,说明没有该单词
if (root.childNodes[k] == null) {
return 0;
} int count = 0;
word = word.substring(1); if (word.length() == 0) {
count = root.childNodes[k].freq;
} else {
count = wordCount(root.childNodes[k], word);
} return count;
}
} /**
* Trie树的节点<br>
* 假定单词都由26个英文字母组成,Trie树根节点不存字符
*/
class TrieNode {
// 孩子节点
public TrieNode[] childNodes;
// 该节点的字符
public char nodeChar; // 以该节点为结束的单词的词频
public int freq;
// 包含该节点的单词的id
public HashSet<Integer> wordSet; // 初始化
public TrieNode() {
childNodes = new TrieNode[CHILD_NUM];
freq = 0;
wordSet = new HashSet<Integer>();
} private static final int CHILD_NUM = 26; public static int getCharPosition(char ch) {
return (ch - 'a');
}
}
测试:
package cn.edu.buaa.trie; /**
* @author zsm
* @date 2016年10月25日 下午3:12:02
* @version 1.0
* @parameter
* @return
*/
public class Main_Trie { public static void main(String[] args) {
// TODO Auto-generated method stub
Trie trie = new Trie();
String wd1 = "ab";
String wd2 = "ac";
String wd3 = "acd"; String wd4 = "add"; trie.addWord(wd1, 1);
trie.addWord(wd2, 2);
trie.addWord(wd2, 3);
trie.addWord(wd3, 4); // wd1,wd2,wd2,wd3
System.out.println(trie.wordCount(wd2));//
System.out.println(trie.wordCount(wd3));//
System.out.println(trie.getTreeSize());//
System.out.println(); trie.deleteWord(wd3, 4);
// wd1,wd2,wd2
System.out.println(trie.wordCount(wd2));//
System.out.println(trie.wordCount(wd3));//
System.out.println(trie.getTreeSize());//
System.out.println(); trie.addWord(wd3, 4);
// wd1,wd2,wd2,wd3
System.out.println(trie.wordCount(wd2));//
System.out.println(trie.wordCount(wd3));//
System.out.println(trie.getTreeSize());//
System.out.println(); trie.deleteWord(wd2, 2);
trie.deleteWord(wd2, 3);
// wd1,wd3
System.out.println(trie.wordCount(wd2));//
System.out.println(trie.wordCount(wd3));//
System.out.println(trie.getTreeSize());//
System.out.println(trie.searchPrefixWord("a"));// [1,4]
System.out.println(); trie.updateWord(wd3, wd4, 4);
// wd1,wd3
System.out.println(trie.searchPrefixWord("a"));// [1,4]
System.out.println(trie.wordCount(wd2));//
System.out.println(trie.wordCount(wd3));//
System.out.println(trie.wordCount(wd4));//
System.out.println(trie.getTreeSize());//
System.out.println(); trie.updateWord(wd4, wd3, 4);
// wd1,wd4
System.out.println(trie.searchPrefixWord("a"));// [1,4]
System.out.println(trie.wordCount(wd2));//
System.out.println(trie.wordCount(wd3));//
System.out.println(trie.wordCount(wd4));//
System.out.println(trie.getTreeSize());//
System.out.println();
}
}
3、参考资料
http://www.cnblogs.com/huangxincheng/archive/2012/11/25/2788268.html
Trie tree实践的更多相关文章
- 字典树(Trie Tree)
终于要开始更新我的ACM学习之路了,不过没想到却是因为一次Java大作业,有趣,%yuan老师. 字典树是一种很简单的树形结构,主要用来进行词频统计,在算法竞赛中有时也会碰到. 字典树的基本思路是,通 ...
- 关于Trie Tree简单实现
最近突然有兴致hiho一下了,实现了下trie tree,感觉而言,还是挺有意思的,个人觉得这货不光可以用来查单词吧,其实也可以用来替代Hash,反正查找,插入复杂度都挺低的,哈哈,啥都不懂,瞎扯.. ...
- 笔试算法题(39):Trie树(Trie Tree or Prefix Tree)
议题:TRIE树 (Trie Tree or Prefix Tree): 分析: 又称字典树或者前缀树,一种用于快速检索的多叉树结构:英文字母的Trie树为26叉树,数字的Trie树为10叉树:All ...
- Phone List POJ 3630 Trie Tree 字典树
Phone List Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 29416 Accepted: 8774 Descr ...
- 字典树(Trie Tree)
在图示中,键标注在节点中,值标注在节点之下.每一个完整的英文单词对应一个特定的整数.Trie 可以看作是一个确定有限状态自动机,尽管边上的符号一般是隐含在分支的顺序中的.键不需要被显式地保存在节点中. ...
- hdu3724Encoded Barcodes(Trie tree)
题目请戳这里 题目大意:给n个字符串,给m个询问,每个询问给k个条形码.每个条形码由8个小码组成,每个小码有相应的宽度,已知一个条形码的宽度只有2种,宽的表示1,窄的表示0.并且宽的宽度是窄的宽度的2 ...
- trie tree(字典树)
hihocoder题目(http://hihocoder.com/problemset):#1014 trie树 #include <iostream> using namespace s ...
- Find the Clones Trie Tree
Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 8306 Accepted: 3130 Description Doubl ...
- 字典树Trie Tree
又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种.典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它的优点是:利用字符串的公共前缀 ...
随机推荐
- 为什么 MySQL 回滚事务也会导致 ibd 文件增大?
一个简单的测试: start transaction; insert into tb1 values(3, repeat('a', 65000),'x',1); --commit; rollback; ...
- MySQL行锁深入研究
原文:http://blog.csdn.net/minipeach/article/details/5325161/ 做项目时由于业务逻辑的需要,必须对数据表的一行或多行加入行锁,举个最简单的例子,图 ...
- [Java入门笔记] 面向对象三大特征之:继承
理解什么是继承 首先我们知道,面对对象有三大特征: 封装:解决了数据的安全性问题 继承:解决了代码的重用问题 多态:解决了程序的扩展问题 上一篇博客中,我们了解了一下封装,现在我了再来看看什么是继承. ...
- springMVC 拦截器如何做登录检查及页面跳转
一个非常简单的登录权限拦截器 问题一:登录页面的提交请求肯定是要过滤掉的,目前采用在xml里配置<mvc:mapping path="/supplier/*"/>来过滤 ...
- hibernate基础dao类
此文章是基于 搭建SpringMVC+Spring+Hibernate平台 功能:数据库的保存.更新.删除:sql.hql查询:分页查询:调用存储过程 创建hibernate基础dao类: BaseD ...
- sql server几种读写分离方案的比较
在生产环境中我们经常会遇到这种情况: 前端的oltp业务很繁忙,但是需要对这些运营数据进行olap,为了不影响前端正常业务,所以需要将数据库进行读写分离. 这里我将几种可以用来进行读写分离的方案总结一 ...
- Linux 目录相关命令(1)
1:分区 分区是指逻辑分区,主分区最多四个,由硬盘结构决定 windows里A和B做软驱判定,C主分区判定 1.硬盘分为若干个等大的扇区 每个扇区默认512字节,其中446字节用于启动信息,64字节用 ...
- Eclipse 安装 jBPM 插件
下载jbpm-installer安装包并解压,找到 jbpm-installer\build.properties搜索eclipse.home 修改 eclipse.home=./eclipse 成 ...
- 【小白的CFD之旅】05 补充基础
黄师姐是一个很干脆果敢的人,从她的日常装扮就能显露出来.卡帕运动装,白色运动鞋,马尾辫,这是小白对黄师姐的第一印象.“明天早上九点钟来实验室,我给你安排这阵子的任务.”黄师姐对小白说.说话语气和老蓝一 ...
- JSP连接数据库,报Unable to compile class for JSP
先看一下报错原因: HTTP Status 500 - Unable to compile class for JSP: type Exception report message Unable to ...