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树的边储存字母,节点存储以该节点结尾的链所代表的字符串 ...
随机推荐
- linux运行.sh命令
# chmod +x AAA.sh 授权 # ./AAA.sh 运行
- [work]Spring_Jdbc
封装Spring-RowMapper,使得使用更加灵活 import java.sql.ResultSet; import java.sql.SQLException; import java.uti ...
- uiautomator 代码记录 :BT接收测试
package rom; import java.lang.*; import java.util.Random; import java.io.File; import com.android.ui ...
- ThinkPHP 小于5.0.24 远程代码执行高危漏洞 修复方案
漏洞描述由于ThinkPHP5.0框架对Request类的method处理存在缺陷,导致黑客构造特定的请求,可直接GetWebShell. 漏洞评级严重 影响版本ThinkPHP 5.0系列 < ...
- MYeclipse 和 flex 环境配置
1安卓JDK 运行 jdk-6u27-windows-i586 安装于 d:/programe/java,注意JRE和JDK安装在一起 测试是否安装成功,运行,CMD,javac 回车.或者java ...
- twisted如何生成deferred的
@implementer(interfaces.IStreamClientEndpoint)class TCP4ClientEndpoint(object): """ ...
- leetcode509
public class Solution { public int Fib(int N) { ) { ; } ) { ; } else { List<int> list = new Li ...
- oracle基础 管理索引
转自:https://blog.csdn.net/without_bont/article/details/79862112 管理索引 --- 原理介绍 索引是用于加速数据存取的数据对象.合 ...
- c++builder 6 [Linker Fatal error] Unable to open file 'PROXIES.OBJ'
c++builder 6 [Linker Fatal error] Unable to open file 'PROXIES.OBJ' http://blog.csdn.net/cb168/artic ...
- 机器学习进阶-图像基本操作-数值计算 1.cv2.add(将图片进行加和) 2.cv2.resize(图片的维度变换) 3.cv2.addWeighted(将图片按照公式进行重叠操作)
1.cv2.add(dog_img, cat_img) # 进行图片的加和 参数说明: cv2.add将两个图片进行加和,大于255的使用255计数 2.cv2.resize(img, (500, ...