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树.前缀树.顾名思义,它是一种针对字符串进行维护的数据结构.并且,它的用途超级广泛.建 ...
随机推荐
- 双系统windows+linux如何正确删除linux
双系统windows+linux如何正确删除linux 2017年11月16日 10:42:49 dovepym 阅读数:26363 之前在windows的基础上又安装了ubuntu系统16.04 ...
- YUV格式与RGB格式
YUV420介绍: YUV420格式是指,每个像素都保留一个Y(亮度)分量,而在水平方向上,不是每行都取U和V分量,而是一行只取U分量,则其接着一行就只取V分量,以此重复(即4:2:0, 4:0:2, ...
- U盘快速启动热键
各个品牌电脑U盘快速启动热键如下:
- P1130 红牌
题目描述 某地临时居民想获得长期居住权就必须申请拿到红牌.获得红牌的过程是相当复杂 ,一共包括NN个步骤.每一步骤都由政府的某个工作人员负责检查你所提交的材料是否符合条件.为了加快进程,每一步政府都派 ...
- java 对象转JSON字符串 $ref 错误
顾名思义,这个是对象转Json时,发生的引用错误. 比较简单的方法是: 使用 帮助方法 https://www.cnblogs.com/hanjun0612/p/9779781.html Conver ...
- springboot 学习
参考:http://www.cnblogs.com/sam-uncle/p/8796212.html spring boot 系列之一:spring boot 入门 注意:main启动类和contro ...
- python成长之路一
1,计算机基础 CPU:中央处理器,相当于人类的大脑,运算中心,控制中心. 内存:暂时储存数据,与CPU交互,8G,16G,32G,64G § 优点:读取速度快. § 缺点:容量小,造价高,断电即消失 ...
- K - Transformation HDU - 4578 线段树经典题(好题)
题意:区间 加 变成定值 乘 区间查询:和 平方和 立方和 思路:超级超级超级麻烦的一道题 设3个Lazy 标记分别为 change 改变mul乘 add加 优先度change>m ...
- scrapy入门与进阶
Scrapy是用纯Python实现一个为了爬取网站数据.提取结构性数据而编写的应用框架,用途非常广泛. 框架的力量,用户只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网页内容以及各种图片,非 ...
- reactNative 基础
参考:中文网,极客 一 . 基本程序: import React, { Component } from 'react'; import { Text } from 'react-native'; e ...