trie数的实现
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数的实现的更多相关文章
- 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 ...
- Trie数 --- 统计公共前缀
<传送门> 统计难题 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131070/65535 K (Java/Others ...
- hdu 1251 统计难题(trie 树的简单应用)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1251 题意:给你多个字符串,求以某个字符串为前缀的字符串数量. 思路:简单的trie数应用,在trie ...
- POJ 3630 Phone List Trie题解
Trie的应用题目. 本题有两个难点了: 1 动态建立Trie会超时,须要静态建立数组,然后构造树 2 推断的时候注意两种情况: 1) Tire树有133,然后插入13333556的时候.2)插入顺序 ...
- 从Trie树到双数组Trie树
Trie树 原理 又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种.它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,能在常数时间O(len)内实现插入和查 ...
- Trie树/字典树题目(2017今日头条笔试题:异或)
/* 本程序说明: [编程题] 异或 时间限制:1秒 空间限制:32768K 给定整数m以及n个数字A1,A2,..An,将数列A中所有元素两两异或,共能得到n(n-1)/2个结果,请求出这些结果中大 ...
- Trie树的二三事QWQ
写在前面 Trie,又称字典树,是一种用于实现字符串快速检索的多叉树结构.Trie的每个结点都拥有若干字符指针,若在插入或检索字符串时扫描到一个字符c,就沿着当前节点的c这个字符指针,走向该指针指向的 ...
- 【Luogu3732】[HAOI2017]供给侧改革(Trie树)
[Luogu3732][HAOI2017]供给侧改革(Trie树) 题面 洛谷 给定一个纯随机的\(01\)串,每次询问\([L,R]\)之间所有后缀两两之间的\(LCP\)的最大值. 题解 一个暴力 ...
- POJ 2418 Hardwood Species 【Trie树】
<题目链接> 题目大意: 给你一堆字符串,让你按字典序输出他们出现的频率. 解题分析: 首先,这是Trie数词频统计的题目,以Trie树的边储存字母,节点存储以该节点结尾的链所代表的字符串 ...
随机推荐
- ubuntu 16.04 静态ip的配置
nssa-sensor1@nssa-sensor1:~$ vim /etc/network/interfaces 以下是编辑文件的内容# interfaces(5) file used by ifup ...
- linux安装chrome浏览器
按照下面的方式安装 wget -P /home/linfu/桌面 https://dl.google.com/linux/direct/google-chrome-stable_current_amd ...
- 为DOM节点添加或者删除class
项目中如果应用了常用的javascript类库,多数情况下,这些已经封装好的类库,都会封装一个类似于addClass和removeClass的方法,以便于我们对DOM节点的class进行操作. 以jQ ...
- oracle的schema的含义
转自:http://www.cnblogs.com/sfmjp/articles/2932748.html 在现在做的Kraft Catalyst 项目中,Cransoft其中有一个功能就是schem ...
- 解决Cell重用问题
在显示的过程中,出现了内容重叠的问题,其实就是UITableViewCell重用机制的问题. 解决方法一:对在cell中添加的控件设置tag的方法 在cell的contentView上需要添加控件,那 ...
- An error was encountered while running(Domain=LaunchSerivcesError, Code=0)
今天突然遇到这样一个错误,编译可以通过,但是运行就会弹出这个错误提示: An error was encountered while running(Domain=LaunchSerivcesErro ...
- 《算法》第一章部分程序 part 1
▶ 书中第一章部分程序,加上自己补充的代码,包括若干种二分搜索,寻找图上连通分量数的两种算法 ● 代码,二分搜索 package package01; import java.util.Arrays; ...
- 序列化 (实现RPC的基础)
public interface ISerializer { <T> byte[] serializer(T obj); <T> T deSerializer(byte[] d ...
- PropertiesUtils
package com.icil.elsa.subscribe.milestone.common.utils; import java.io.BufferedInputStream; import j ...
- 【ASP.NET 问题】IIS发布网站后出现“检测到在集成的托管管道模式下不适用的ASP.NET设置”的解决办法
系统环境:win7 asp.net4.0网站挂到本地IIS上报错: google一下,发现N页解决方案,但是点进去一看前篇一律的解决方法是.将IIS7 下网站托管管道由继承模式修改为经典模式,这其实是 ...