Trie树又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希表高。

      这里的需求是,给如一组词汇,北京人,北京,武汉,武汉话等等。能够统计“武汉”这个词的词频,输入"武"的时候,能够得到以“武”开头的所有词。实现的代码如下:

package com.dong.util;

import java.util.ArrayList;
import java.util.List; public class Trie {
// 根节点
private final TrieNode root = new TrieNode(' '); // 向trie树中插入一个词
public void insert(String word) {
if (word == null || word.length() == 0) {
return;
}
String left = word;
TrieNode cur = root;
while (left.length() > 0) {
char toInert = left.charAt(0);
TrieNode next = null;
// 如果那个节点不存在的话,将当前节点插入
if (containCharNode(cur.getChild(), toInert) == null) {
next = new TrieNode(toInert);
cur.getChild().add(next);
} else {
next = containCharNode(cur.getChild(), toInert);
}
cur = next;
left = left.substring(1);
if (left.length() == 0) {
cur.setFreq(cur.getFreq() + 1);
}
}
} // 通过前缀查找词,返回包括前缀的所有词。
public List<String> search(String prefix) {
List<String> retList = new ArrayList<String>();
List<String> tempList = new ArrayList<String>();
if (prefix == null || prefix.length() == 0) {
return null;
}
String left = prefix;
TrieNode cur = root;
while (left.length() > 0) {
char toFind = left.charAt(0);
TrieNode next = null;
// 如果那个节点不存在的话,将当前节点插入
if (containCharNode(cur.getChild(), toFind) == null) {
return null;
} else {
next = containCharNode(cur.getChild(), toFind);
if (left.length() == 1) {
cur = next;
break;
}
}
cur = next;
left = left.substring(1); } dfs(cur, new ArrayList<Character>(), tempList);
for (String s : tempList) {
retList.add(prefix + s);
} if (getFreq(prefix) > 0) {
retList.add(prefix); }
return retList;
} // 深度搜索一个trieNode节点下的所有的词
private void dfs(TrieNode root, List<Character> stack, List<String> retList) {
if (root.getChild().size() == 0) {
StringBuffer sb = new StringBuffer();
for (char c : stack) {
sb.append(c);
}
retList.add(sb.toString()); } else {
for (TrieNode r : root.getChild()) {
stack.add(r.getVal());
dfs(r, stack, retList);
stack.remove(stack.size() - 1);
}
} } // 查看一个节点的的子节点是否包含一个字符
public TrieNode containCharNode(List<TrieNode> child, char c) {
TrieNode ret = null;
for (TrieNode temp : child) {
if (temp.getVal() == c) {
ret = temp;
}
}
return ret; } // 得到一个词的词频
public int getFreq(String word) {
if (word == null || word.length() == 0) {
return 0;
}
String left = word;
TrieNode cur = root;
while (left.length() > 0) {
char toFind = left.charAt(0);
TrieNode next = null;
// 如果不存在此节点,返回0
if (containCharNode(cur.getChild(), toFind) == null) {
return 0;
} else {
next = containCharNode(cur.getChild(), toFind);
if (left.length() == 1) {
cur = next;
break;
}
}
cur = next;
left = left.substring(1); }
return cur.getFreq();
} public static String fill(String prefix, ArrayList<Character> stack) {
ArrayList<String> retList = new ArrayList<String>();
StringBuffer sb = new StringBuffer();
sb.append(prefix);
for (char c : stack) {
sb.append(c);
}
return sb.toString(); } public static void main(String[] args) {
Trie t = new Trie();
String[] wordList = { "我晕", "我晕啊", "我不信啊", "我信了", "也是", "这不对啊", "我晕" };
for (String word : wordList) {
t.insert(word);
}
System.out.println(t.search("我晕")); }
} class TrieNode {
// 节点下存放的字符
private char val;
// 一个节点下面的子节点
private List<TrieNode> child;
// 该词的词频
private int freq; public TrieNode(char val) {
child = new ArrayList();
freq = 0;
this.val = val; } public char getVal() {
return val;
} public void setVal(char val) {
this.val = val;
} public List<TrieNode> getChild() {
return child;
} public void setChild(List<TrieNode> child) {
this.child = child;
} public int getFreq() {
return freq;
} public void setFreq(int freq) {
this.freq = freq;
}
}

trie数的实现的更多相关文章

  1. Educational Codeforces Round 23 E. Choosing The Commander trie数

    E. Choosing The Commander time limit per test 2 seconds memory limit per test 256 megabytes input st ...

  2. Trie数 --- 统计公共前缀

    <传送门> 统计难题 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131070/65535 K (Java/Others ...

  3. hdu 1251 统计难题(trie 树的简单应用)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1251 题意:给你多个字符串,求以某个字符串为前缀的字符串数量. 思路:简单的trie数应用,在trie ...

  4. POJ 3630 Phone List Trie题解

    Trie的应用题目. 本题有两个难点了: 1 动态建立Trie会超时,须要静态建立数组,然后构造树 2 推断的时候注意两种情况: 1) Tire树有133,然后插入13333556的时候.2)插入顺序 ...

  5. 从Trie树到双数组Trie树

    Trie树 原理 又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种.它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,能在常数时间O(len)内实现插入和查 ...

  6. Trie树/字典树题目(2017今日头条笔试题:异或)

    /* 本程序说明: [编程题] 异或 时间限制:1秒 空间限制:32768K 给定整数m以及n个数字A1,A2,..An,将数列A中所有元素两两异或,共能得到n(n-1)/2个结果,请求出这些结果中大 ...

  7. Trie树的二三事QWQ

    写在前面 Trie,又称字典树,是一种用于实现字符串快速检索的多叉树结构.Trie的每个结点都拥有若干字符指针,若在插入或检索字符串时扫描到一个字符c,就沿着当前节点的c这个字符指针,走向该指针指向的 ...

  8. 【Luogu3732】[HAOI2017]供给侧改革(Trie树)

    [Luogu3732][HAOI2017]供给侧改革(Trie树) 题面 洛谷 给定一个纯随机的\(01\)串,每次询问\([L,R]\)之间所有后缀两两之间的\(LCP\)的最大值. 题解 一个暴力 ...

  9. POJ 2418 Hardwood Species 【Trie树】

    <题目链接> 题目大意: 给你一堆字符串,让你按字典序输出他们出现的频率. 解题分析: 首先,这是Trie数词频统计的题目,以Trie树的边储存字母,节点存储以该节点结尾的链所代表的字符串 ...

随机推荐

  1. CSS的4种定位方式比较

    CSS有四种定位(Positioning)方法:Static,Relative, Absolute和Fixed 元素flow, overlap 相对参照物: 能否用offset( top, left, ...

  2. Android悬浮框,在Service中打开悬浮窗;在Service中打开Dialog;

    文章介绍了如何在Service中显示悬浮框,在Service中弹出Dialog,在Service中做耗时的轮询操作: 背景需求: 公司的项目现在的逻辑是这样的:发送一个指令,然后3秒一次轮询去查询这个 ...

  3. CentOS7上安装RabbitMQ

    1.首先需要安装erlang RabbitMq依赖于erlang,所以得先装这个.推荐使用阿里云的镜像资源. 通过这个链接 https://opsx.alibaba.com/mirror/search ...

  4. Spring MVC 学习笔记11 —— 后端返回json格式数据

    Spring MVC 学习笔记11 -- 后端返回json格式数据 我们常常听说json数据,首先,什么是json数据,总结起来,有以下几点: 1. JSON的全称是"JavaScript ...

  5. uva-10422-骑士-搜索题

    题意: 给你一个5X5的图,棋盘上骑士的走法自己去百度,问能不能在10步内走到目标图, 解题思路: 从目标图开始往前走10步,保存所有能走到的图,然后输入,查找是否存在这个图,存在就是可以走到,不存在 ...

  6. 1.1使用java数组,并开始封装我们自己的数组

    今天感冒了,全身酸软无力,啥样不想做,就来学习吧,此节我们从初步使用java中提供的数组,然后分析相关情况,过渡到封装我们自己的数组. 一.我们先来感受一下java提供的数组,以整型数组(int[]) ...

  7. mybatis四(动态sql)

    <1><select id="selectUserByConditions" parameterType="user" resultType= ...

  8. Python Requests库网络爬取全代码

    #爬取京东商品全代码 import requestsurl = "http://item.jd.com/2967929.html"try: r = requests.get(url ...

  9. asp.net Log4Net错误日志个人总结

    1)创建Global.asax protected void Application_Start(object sender, EventArgs e) { log4net.Config.XmlCon ...

  10. makefile中 $@, $^, $<, $?含义

    $@ 表示目标文件 $^ 表示所有的依赖文件 $< 表示第一个依赖文件 $? 表示比目标还要新的依赖文件列表 例子 root_num.exe: root_num.o my_root.o gcc ...