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树的边储存字母,节点存储以该节点结尾的链所代表的字符串 ...
随机推荐
- jQuery实现点击控制左右两边元素挤压显示效果
该功能实现的是:分左.右两边布局,左边div默认展开,左边div中有一个元素,点击实现左边div隐藏,右边div挤压过来:再点击实现左边显示,右边挤过去. 一.HTML代码: <div clas ...
- Dom4j解析、生成Xml
1以下代码未Xml的解析和生成代码 <?xml version="1.0" encoding="UTF-8"?> <users> < ...
- alias with parameter,linux
alias demoAlias1='_(){ git checkout -b $1; command2;}; _'
- IDEA集成git和使用步骤
2018年07月20日 11:26:29 完猛 阅读数:3246 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/miwanmeng/artic ...
- [Unity算法]弧度和角度
参考链接: https://zhidao.baidu.com/question/576596182.html 1.弧度和角度的转换 2.sin函数 3.cos函数 4.tan函数 5.特殊的三角函数值 ...
- 关于 Glassfish
GlassFish 是一款强健的商业兼容应用服务器,达到产品级质量,可免费用于开发.部署和重新分发.开发者可以免费获得源代码,还可以对代码进行更改 GlassFish 是用于构建 Java EE 5应 ...
- php图片上传base64数据编码。
/** * base64图片上传 */ function IdImg($base64_img = ''){ $up_dir = 'upload/';//存放在当前目录的upload文件夹下 if(!f ...
- git 简单的操作命令
1, 克隆已存在项目 => git clone url 2, 拉取代码 => git pull 3, 配置账号密码 git config --global user.email &quo ...
- centos7.5安装VirtualBox
centos7.5安装minikube时要求先安装VirtualBox 1.准备repo文件 [root@localhost yum.repos.d]# pwd /etc/yum.repos.d [r ...
- mac 命令行上传文件,mac tar.gz命令压缩
在mac上可以直接打开命令行给服务器上传文件,注意是本地的命令行,不是服务器的命令行,我就走了绕路 命令可以看这里https://www.cnblogs.com/hitwtx/archive/2011 ...