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)的更多相关文章

  1. Java数据结构——字典树TRIE

    又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种. 典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计. 它的优点是:利用字符串的公共 ...

  2. K:单词查找树(Trie)

      单词查找树,又称前缀树或字典树,是一种有序树,用于保存关联数组,其中的键通常是字符串.Trie可以看作是一个确定有限状态自动机(DFA).与二叉查找树不同,键不是直接保存在节点中,而是由节点在树中 ...

  3. 字典树(Trie树)的实现及应用

    >>字典树的概念 Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树.与二叉查找树不同,Trie树的 ...

  4. Atitit 常见的树形结构 红黑树  二叉树   B树 B+树  Trie树 attilax理解与总结

    Atitit 常见的树形结构 红黑树  二叉树   B树 B+树  Trie树 attilax理解与总结 1.1. 树形结构-- 一对多的关系1 1.2. 树的相关术语: 1 1.3. 常见的树形结构 ...

  5. 字典树trie的学习与练习题

    博客详解: http://www.cnblogs.com/huangxincheng/archive/2012/11/25/2788268.html http://eriol.iteye.com/bl ...

  6. 『字典树 trie』

    字典树 (trie) 字典树,又名\(trie\)树,是一种用于实现字符串快速检索的树形数据结构.核心思想为利用若干字符串的公共前缀来节约储存空间以及实现快速检索. \(trie\)树可以在\(O(( ...

  7. 字典树trie学习

    字典树trie的思想就是利用节点来记录单词,这样重复的单词可以很快速统计,单词也可以快速的索引.缺点是内存消耗大 http://blog.csdn.net/chenleixing/article/de ...

  8. 字典树Trie的使用

    1. Trie树介绍 Trie,又称单词查找树.前缀树,是一种多叉树结构.如下图所示: 上图是一棵Trie树,表示了关键字集合{“a”, “to”, “tea”, “ted”, “ten”, “i”, ...

  9. 字典树(Trie)详解

    详解字典树(Trie) 本篇随笔简单讲解一下信息学奥林匹克竞赛中的较为常用的数据结构--字典树.字典树也叫Trie树.前缀树.顾名思义,它是一种针对字符串进行维护的数据结构.并且,它的用途超级广泛.建 ...

随机推荐

  1. SQL 给视图赋权限

    授予表权限 创建视图 授予视图权限 测试权限 复杂程度: 初级 数据要求: 使用自备的数据 您可以使用 SQL 在企业级地理数据库中创建表和要素类的视图. 本主题中的示例显示如何使用 Microsof ...

  2. Upload Files In ASP.NET Core 1.0 (Form POST And JQuery Ajax)

    Uploading files is a common requirement in web applications. In ASP.NET Core 1.0 uploading files and ...

  3. ES6字符串操作

    讨论字符串操作之前,我们先来了解一下Unicode 编码的由来,因为Js中的字符串就是一系列Unicode码的集合. 我们都知道,世界上存在着各种各样的语言,汉语,英语,日语等,相对应的,也就存在各种 ...

  4. DRF 版本 认证

    DRF的版本 版本控制是做什么用的, 我们为什么要用 首先我们要知道我们的版本是干嘛用的呢大家都知道我们开发项目是有多个版本的 当我们项目越来越更新~版本就越来越多我们不可能新的版本出了~以前旧的版本 ...

  5. linux不能上网问题

    第一种方法: 当linux不能上网,将网络配置成dhcp(注意:这里只能小写) onboot设置能yes 第二种方法: 第三种 window+r 快捷键 HKEY_LOCAL_MACHINE--> ...

  6. BZOJ4946[Noi2017]蔬菜——线段树+堆+模拟费用流

    题目链接: [Noi2017]蔬菜 题目大意:有$n$种蔬菜,每种蔬菜有$c_{i}$个,每种蔬菜每天有$x_{i}$个单位会坏掉(准确来说每天每种蔬菜坏掉的量是$x_{i}-$当天这种蔬菜卖出量), ...

  7. hiho1255 Mysterious Antiques in Sackler Museum

    题目链接:http://media.hihocoder.com/contests/icpcbeijing2015/problems.pdf 题目大意:给你四个矩形,判断是否能取其中任意三个组成一个大矩 ...

  8. windows下操作linux虚拟机映射网络驱动器中文件提示chmod权限不足解决方案

    为了方便操作,linux虚拟机会通过windows下连接网络驱动器的方式共享自己的文件,对于前端来说,我想把gulp放在windows磁盘,操作虚拟机中的php文件,一来节省虚拟机磁盘大小,二来解决虚 ...

  9. 深度分析Java的枚举类型—-枚举的线程安全性及序列化问题

    原文:深度分析Java的枚举类型--枚举的线程安全性及序列化问题 枚举是如何保证线程安全的 要想看源码,首先得有一个类吧,那么枚举类型到底是什么类呢?是enum吗?答案很明显不是,enum就和clas ...

  10. 【BZOJ5470】[FJOI2018]所罗门王的宝藏()

    [BZOJ5470][FJOI2018]所罗门王的宝藏() 题面 BZOJ 洛谷 有\(n+m\)个变量,给定\(k\)组限制,每次告诉你\(a_i+b_j=c_k\),问是否有可行解. 题解 一道很 ...