Java实现单词树(trie)
package com.shundong.utils; import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; /**
* 一个只能处理26个字母的单词树(trie)
* 空间换时间 T(n) = O(n)
* ps:如果缺陷 欢迎留言
* @author shundong
* @data 2018-10-13
*/ public class FindWordsTrie{
//一个Trie树有一个根节点
private Vertex root; //内部类or节点类
protected class Vertex{
protected int words;
protected int prefixes;
//每个节点包含26个子节点(类型为自身)
protected Vertex[] edges;
Vertex() {
words = 0;
prefixes = 0;
edges = new Vertex[26];
for (int i = 0; i < edges.length; i++) {
edges[i] = null;
}
}
} public FindWordsTrie () {
root = new Vertex();
} /**
* 列出List所有单词
* @return
*/
public List< String> listAllWords() { List< String> words = new ArrayList< String>();
Vertex[] edges = root.edges; for (int i = 0; i < edges.length; i++) {
if (edges[i] != null) {
String word = "" + (char)('a' + i);
depthFirstSearchWords(words, edges[i], word);
}
}
return words;
} /**
* Depth First在Trie中搜索单词并将它们添加到List中。
* @param words
* @param vertex
* @param wordSegment
*/
private void depthFirstSearchWords(List words, Vertex vertex, String wordSegment) {
Vertex[] edges = vertex.edges;
boolean hasChildren = false;
for (int i = 0; i < edges.length; i++) {
if (edges[i] != null) {
hasChildren = true;
String newWord = wordSegment + (char)('a' + i);
depthFirstSearchWords(words, edges[i], newWord);
}
}
if (!hasChildren) {
words.add(wordSegment);
}
} public int countPrefixes(String prefix) {
return countPrefixes(root, prefix);
} private int countPrefixes(Vertex vertex, String prefixSegment) {
if (prefixSegment.length() == 0) { //到达单词的最后一个字符
return vertex.prefixes;
}
char c = prefixSegment.charAt(0);
int index = c - 'a';
if (vertex.edges[index] == null) { // 这个词不存在
return 0;
} else {
return countPrefixes(vertex.edges[index], prefixSegment.substring(1));
}
} public int countWords(String word) {
return countWords(root, word);
} private int countWords(Vertex vertex, String wordSegment) {
if (wordSegment.length() == 0) { //到达单词的最后一个字符
return vertex.words;
}
char c = wordSegment.charAt(0);
int index = c - 'a';
if (vertex.edges[index] == null) { // 这个词不存在
return 0;
} else {
return countWords(vertex.edges[index], wordSegment.substring(1));
} }
/**
* 在Trie上添加一个单词
* @param word 要添加的词
*/
public void addWord(String word) {
addWord(root, word);
}
/**
* 添加指定顶点的单词
* @param vertex 指定的顶点
* @param word 要添加的词
*/
private void addWord(Vertex vertex, String word) {
if (word.length() == 0) { //如果已添加该单词的所有字符
vertex.words ++;
} else {
vertex.prefixes ++;
char c = word.charAt(0);
c = Character.toLowerCase(c);
int index = c - 'a';
if (vertex.edges[index] == null) { //如果边缘不存在
vertex.edges[index] = new Vertex();
}
addWord(vertex.edges[index], word.substring(1)); //去下一个
}
}
//简单的测试测试
public static void main(String args[])
{
FindWordsTrie trie = new FindWordsTrie();
trie.addWord("cabbage");
trie.addWord("cabbage");
trie.addWord("cabbage");
trie.addWord("cabbage");
trie.addWord("cabin");
trie.addWord("berte");
trie.addWord("cabbage");
trie.addWord("english");
trie.addWord("establish");
trie.addWord("good"); // System.out.println(trie.root.prefixes);
// System.out.println(trie.root.words);
// List< String> list = trie.listAllWords();
// Iterator listiterator = list.listIterator();
// //遍历
// while(listiterator.hasNext())
// {
// String str = (String)listiterator.next();
// System.out.println(str);
// }
int count = trie.countPrefixes("c");//此处传参
int count1=trie.countWords("cabbage");
System.err.println("单词c 前缀个数为:"+count);
System.err.println("cabbage 单词的个数为:"+count1);
}
}
Java实现单词树(trie)的更多相关文章
- Java数据结构——字典树TRIE
又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种. 典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计. 它的优点是:利用字符串的公共 ...
- K:单词查找树(Trie)
单词查找树,又称前缀树或字典树,是一种有序树,用于保存关联数组,其中的键通常是字符串.Trie可以看作是一个确定有限状态自动机(DFA).与二叉查找树不同,键不是直接保存在节点中,而是由节点在树中 ...
- 字典树(Trie树)的实现及应用
>>字典树的概念 Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树.与二叉查找树不同,Trie树的 ...
- Atitit 常见的树形结构 红黑树 二叉树 B树 B+树 Trie树 attilax理解与总结
Atitit 常见的树形结构 红黑树 二叉树 B树 B+树 Trie树 attilax理解与总结 1.1. 树形结构-- 一对多的关系1 1.2. 树的相关术语: 1 1.3. 常见的树形结构 ...
- 字典树trie的学习与练习题
博客详解: http://www.cnblogs.com/huangxincheng/archive/2012/11/25/2788268.html http://eriol.iteye.com/bl ...
- 『字典树 trie』
字典树 (trie) 字典树,又名\(trie\)树,是一种用于实现字符串快速检索的树形数据结构.核心思想为利用若干字符串的公共前缀来节约储存空间以及实现快速检索. \(trie\)树可以在\(O(( ...
- 字典树trie学习
字典树trie的思想就是利用节点来记录单词,这样重复的单词可以很快速统计,单词也可以快速的索引.缺点是内存消耗大 http://blog.csdn.net/chenleixing/article/de ...
- 字典树Trie的使用
1. Trie树介绍 Trie,又称单词查找树.前缀树,是一种多叉树结构.如下图所示: 上图是一棵Trie树,表示了关键字集合{“a”, “to”, “tea”, “ted”, “ten”, “i”, ...
- 字典树(Trie)详解
详解字典树(Trie) 本篇随笔简单讲解一下信息学奥林匹克竞赛中的较为常用的数据结构--字典树.字典树也叫Trie树.前缀树.顾名思义,它是一种针对字符串进行维护的数据结构.并且,它的用途超级广泛.建 ...
随机推荐
- c++中结构体sort()排序
//添加函数头 #include <algorithm> //定义结构体Yoy typedef struct { double totalprice; //总价 doubl ...
- Nginx 优化缓冲区与传输效率
L:126 这里简单的做个计算 比如 我的服务器带宽是 5M=41943040字节 如果按照公网用PIND的得到延迟结果 icmp_seq=3 ttl=49 time=35.612 ms BDP = ...
- Qt QLabel的使用
QLabel类主要用来文本和图像的显示,没有提供用户交互功能.QLabel对象的视觉外观可以由用户自定义配置. 它还可以为另外一个可获得焦点的控件作为焦点助力器. QLabel可以显示下列的所有类型: ...
- 百度分享不支持https的解决方案(单独部署静态文件)
首先是参考了博客,下载百度分享的静态代码 static 链接为:https://www.cnblogs.com/mmzuo-798/p/6434576.html 后来在nginx的 nginx.con ...
- 普通Splay详解
预备知识: 二叉搜索树(BST) 至于BST,随便看一下就可以, 我们知道二叉搜索树是O(logN)的,那我们为什么要用平衡树呢? 之前我们了解到,BST的插入是小的往左子树走,大的往右子树走,如果凉 ...
- mysql 2006错误 导入时
导入数据库报此错误 1.找到my.ini (免安装版的是由于你自己创建的) (安装版的在 C:\ProgramData\MySQL\MySQL Server 8.0 你安装的盘位置) 2.修改参数 ...
- Navicat再次激活
换了个新电脑,上一次激活用的注册机老被杀掉,defender什么的都关了,不知道是谁在暗中保护我的电脑.. 上个激活参考:https://www.cnblogs.com/MC-Curry/p/9765 ...
- 【dp】P1434 [SHOI2002]滑雪
题目描述 Michael喜欢滑雪.这并不奇怪,因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道在一个区域中最长 ...
- [HNOI2010]物品调度
题目描述 现在找工作不容易,Lostmonkey费了好大劲才得到fsk公司基层流水线操作员的职位.流水线上有n个位置,从0到n-1依次编号,一开始0号位置空,其它的位置i上有编号为i的盒子.Lostm ...
- BJWC2018上学路线
题目描述 小B 所在的城市的道路构成了一个方形网格,它的西南角为(0,0),东北角为(N,M). 小B 家住在西南角,学校在东北角.现在有T 个路口进行施工,小B 不能通过这些路口.小B 喜欢走最短的 ...