package test;
import java.util.ArrayList;
import java.util.List;
public class Trie {
private Vertex root = new Vertex();
protected class Vertex {
protected int words; // 单词个数
protected int prefixes; // 前缀个数
protected Vertex[] edges; // 子节点
Vertex() {
this.words = 0;
this.prefixes = 0;
edges = new Vertex[26];
for (int i = 0; i < edges.length; i++) {
edges[i] = null;
}
}
}
/**
* 获取tire树中所有的词
*
* @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;
}
/**
*
* @param words
* @param vertex
* @param wordSegment
*/
private void depthFirstSearchWords(List words, Vertex vertex,
String wordSegment) {
if (vertex.words != 0) {
words.add(wordSegment);
}
Vertex[] edges = vertex.edges;
for (int i = 0; i < edges.length; i++) {
if (edges[i] != null) {
String newWord = wordSegment + (char) ('a' + i);
depthFirstSearchWords(words, edges[i], newWord);
}
}
}
/**
* 计算指定前缀单词的个数
*
* @param prefix
* @return
*/
public int countPrefixes(String prefix) {
return countPrefixes(root, prefix);
}
private int countPrefixes(Vertex vertex, String prefixSegment) {
if (prefixSegment.length() == 0) { // reach the last character of the
// word
return vertex.prefixes;
}
char c = prefixSegment.charAt(0);
int index = c - 'a';
if (vertex.edges[index] == null) { // the word does NOT exist
return 0;
} else {
return countPrefixes(vertex.edges[index],
prefixSegment.substring(1));
}
}
/**
* 计算完全匹配单词的个数
*
* @param word
* @return
*/
public int countWords(String word) {
return countWords(root, word);
}
private int countWords(Vertex vertex, String wordSegment) {
if (wordSegment.length() == 0) { // reach the last character of the word
return vertex.words;
}
char c = wordSegment.charAt(0);
int index = c - 'a';
if (vertex.edges[index] == null) { // the word does NOT exist
return 0;
} else {
return countWords(vertex.edges[index], wordSegment.substring(1));
}
}
/**
* 向tire树添加一个词
*
* @param word
*
*/
public void addWord(String word) {
addWord(root, word);
}
/**
* Add the word from the specified vertex.
*
* @param vertex
* The specified vertex.
* @param word
* The word to be added.
*/
private void addWord(Vertex vertex, String word) {
if (word.length() == 0) { // if all characters of the word has been
// added
vertex.words++;
} else {
vertex.prefixes++;
char c = word.charAt(0);
c = Character.toLowerCase(c);
int index = c - 'a';
if (vertex.edges[index] == null) { // if the edge does NOT exist
vertex.edges[index] = new Vertex();
}
addWord(vertex.edges[index], word.substring(1)); // go the the next
// character
}
}
/**
* 返回指定字段前缀匹配最长的单词。
*
* @param word
* @return
*/
public String getMaxMatchWord(String word) {
String s = "";
String temp = "";// 记录最近一次匹配最长的单词
char[] w = word.toCharArray();
Vertex vertex = root;
for (int i = 0; i < w.length; i++) {
char c = w[i];
c = Character.toLowerCase(c);
int index = c - 'a';
if (vertex.edges[index] == null) {// 如果没有子节点
if (vertex.words != 0)// 如果是一个单词,则返回
return s;
else
// 如果不是一个单词则返回null
return null;
} else {
if (vertex.words != 0)
temp = s;
s += c;
vertex = vertex.edges[index];
}
}
// trie中存在比指定单词更长(包含指定词)的单词
if (vertex.words == 0)//
return temp;
return s;
}
public static void main(String args[]) // Just used for test
{
Trie trie = new Trie();
trie.addWord("abcedfddddddd");
trie.addWord("a");
trie.addWord("ba");
trie.addWord("abce");
trie.addWord("abcedfdddd");
trie.addWord("abcef");
String maxMatch = trie.getMaxMatchWord("abcedfddd");
System.out.println(maxMatch);
// List<String> list = trie.listAllWords();
// Iterator listiterator = list.listIterator();
// while (listiterator.hasNext()) {
// String s = (String) listiterator.next();
// System.out.println(s);
// }
// int count = trie.countPrefixes("abcdef");
// int count1 = trie.countWords("abcd");
// System.out.println("prefixes:" + count);
// System.out.println("countWords:" + count1);
}
}
分享到:
相关推荐
Trie树,又称字典树或前缀树,关于它的结构就不详细介绍了。Trie树在单词统计、前缀匹配等很多方面有很大用处...下面这篇文章主要介绍了Trie树,以及Java实现如何Trie树,有需要的朋友可以参考借鉴,下面来一起看看吧。
java数组 java数组_基于java实现的双数组Trie树
基于Java链表实现的字典树(trie),实现了增删改查等功能,它说摘要必须大于50字我还能说啥啥啥啥
Java实现字典树TrieTree,可用于计算出四六级试题的高频词.
主要介绍了Java中实现双数组Trie树实例,双数组Trie就是一种优化了空间的Trie树,本文给出了实现代码、测试代码和测试结果,需要的朋友可以参考下
DoubleArrayTrie Java编写的DoubleArrayTrie介绍用法// construct and buildDoubleArrayTrie dat = new DoubleArrayTrie(); for(String word: words) { dat.Insert(word); } System.out.println(dat.Base.length); ...
Prefix Trie数据结构的Java实现。 介绍 尝试是类似于基于有序树的数据结构的地图,可快速搜索O(k)的顺序,其中k是键的长度。 阅读有关trie的更多信息。 动机 它最初是为在我的Android应用程序T9 App Launcher中使用...
Java字典树实现。 精简优化版处理。适合Java屏蔽字并进行。进行检测并处理的情况
给定算术表达式的DFA图,利用Java语言构建Trie树,实现对输入文法的判断
Java中的Trie和Levenshtein距离混合实现,可实现极快的前缀字符串搜索和字符串相似性。 作者:Umberto Griffo 推特:@UmbertoGriffo内容特里定义Trie [1]是使用字符串作为键的有序树数据结构。 这是一种有效的信息...
在 Java 中实现的并发非阻塞 patricia 树。 此树支持整数键并使用基于边缘的锁定来改进内存和性能。 这是作为德切夫博士在 UCF 的并行算法和编程 (COP4520) 课程的最终项目完成的。 该存储库还包括一篇用 LaTeX 编写...
一棵用List来存储子结点的字典树——当然,也可以用哈希表等形式存储。 这篇笔记记录了构建思路,文末是源码 一、构建思路 Step1 设计结点——数据结构 Step2 实现相应的操作方法——增删改查 Step1 设计结点 我们...
字典树(Trie)可以保存一些字符串->值的对应关系。基本上,它跟 Java 的 HashMap 功能相同,都...至于Trie树的实现,可以用数组,也可以用指针动态分配,我做题时为了方便就用了数组,静态分配空间。 Trie树,又称单词
Java的灵活的实现,提供了与前缀相关的操作的丰富功能。 它实现了接口,并且可以使用任何类型的对象作为键,只要可以通过专门的BitwiseComparator将它们按位进行比较BitwiseComparator 。 与相比,它具有相对的性能...
复杂度 时间复杂度 空间复杂度 线性数据结构动态数组(ArrayList) ...Trie 线性+树形数据结构 集合(HashSet) 映射(HashMap、LinkedHashMap) 二叉堆(BinaryHeap) 优先级队列(PriorityQueue)
基数树(也称为 patricia trie、radix trie或紧凑前缀树)是一种空间优化的树数据结构,它允许仅使用键的前缀插入键(以及与这些键相关联的可选值)以供后续查找而不是整个密钥。 基数树在字符串或文档索引和扫描...
Trie树(来自单词retrieval),又称前缀字,单词查找树,字典树,是一种树形结构,是一种哈希树的变种,是一种用于快速检索的多叉树结构。 它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。 Trie...
后缀Trie树的java实现 标签:suffixTrie
可变长数组和字典树Java代码实现。比较容易复制和学习。
实施为Java NavigableMap的自适应基数树 该库基于ICDE 2013“自适应基数树:主存数据库的ARTful索引”,以的形式提供了自适应基数树(ART)的实现。 在有序数据结构的空间中,特别有趣,因为它们的高度和时间...