Mysql前缀树_前缀树(Trie树,字典树)

给出字符串,如“abc”

从头结点开始,依次检查,有没有走向a的路,如果没有,就新建出来,a作为路上的值(不是结点的值),如果有的话,就复用

f09e8c9c76262706d9bf5fe0e69ff93f.png

在字符串的结尾处的结点的值+1,表示有一个是以该字符串结尾的

1.可以查是否某个字符串是以某个字符串为前缀的

2.还可以查 添加了几次该前缀  (有多少字符串是以该结点结尾的)

3.还可以查有多少个字符串是以字符串作为前缀的(前缀的词频是多少)(有多少字符串到达过该结点)

插入字符串:public void insert(String str)

删除字符串:public void delete(String str)

在前缀树中查询字符串出现的次数:public int search(String str)

在前缀树中查询以str字符串为前缀的个数:public int prefixNumber(String str)

public class TrieTree {

//前缀树的结构

public static class TrieNode{

//表示扫过当前结点多少次

public int path;

//表示以当前结点结尾的次数

public int end;

//表示当前结点的下一个结点(从a-z) 同时,数组中对应的位置就是a-z字母的顺序

// 如果想表示其他类型的,可以使用HashMap nexts;

// key表示的是边的ASCII码,value表示对应的下一个结点

public TrieNode[] nexts;

public TrieNode(){

path = 0;

end = 0;

nexts = new TrieNode[26];

}

}

public static class Trie{

//前缀树的头结点 为空

private TrieNode root;

public Trie(){

root = new TrieNode();

}

/**

* 将一个字符串加入前缀树,即向前缀树中添加路径和结点,

* 首先检查前缀树中是否含有当前结点,

* 如果存在的话,则将其路径上的path++,end++,

* 如果不存在某几个结点的话,则创建出来

* @param str

*/

public void insert(String str){

if(str == null || str.length() == 0) return;

char[] ch = str.toCharArray();

TrieNode trieNode = root;

for(int i = 0; i < ch.length; i++){

int index = ch[i] - 'a';

//该元素不存在,则创建出来

if(trieNode.nexts[index] == null){

trieNode.nexts[index] = new TrieNode();

}

trieNode = trieNode.nexts[index];

trieNode.path++;

}

trieNode.end++;

}

/**

* 删除指定字符串对应在前缀树中的路径

* 在前缀树中查找,然后依次将其path-1,

* 当path==0时,直接将其置为null即可(后面的结点都可以不要了)

* @param str

*/

public void delete(String str){

if(str == null || str.length() == 0) return;

char[] ch = str.toCharArray();

TrieNode trieNode = root;

for(int i = 0; i < ch.length; i++){

int index = ch[i] - 'a';

if(--trieNode.nexts[index].path == 0){

trieNode.nexts[index] = null;

return;

}

trieNode = trieNode.nexts[index];

}

trieNode.end--;

}

/**

* 查询一个字符串在前缀树中出现了多少次

* 如果一路下来都存在,则返回end中的值,

* 如果过程中含有不存在的值,则返回0

* @param str

* @return

*/

public int search(String str){

if(str == null || str.length() == 0) return 0;

char[] ch = str.toCharArray();

TrieNode trieNode = root;

for(int i = 0; i < ch.length; i++){

int index = ch[i] - 'a';

if(trieNode.nexts[index] == null) return 0;

trieNode = trieNode.nexts[index];

}

return trieNode.end;

}

/**

* 查找以str为前缀的字符有多少

* 即查找以str为路径的path是多少

* @param str

* @return

*/

public int prefixNumber(String str){

if(str == null || str.length() == 0) return 0;

char[] ch = str.toCharArray();

TrieNode trieNode = root;

for(int i = 0; i < ch.length; i++){

int index = ch[i] - 'a';

if(trieNode.nexts[index] == null) return 0;

trieNode = trieNode.nexts[index];

}

return trieNode.path;

}

public static void main(String[] args) {

Trie trie = new Trie();

System.out.println(trie.search("zuo"));

trie.insert("zuo");

System.out.println(trie.search("zuo"));

trie.delete("zuo");

System.out.println(trie.search("zuo"));

trie.insert("zuo");

trie.insert("zuo");

trie.delete("zuo");

System.out.println(trie.search("zuo"));

trie.delete("zuo");

System.out.println(trie.search("zuo"));

trie.insert("zuoa");

trie.insert("zuoac");

trie.insert("zuoab");

trie.insert("zuoad");

trie.delete("zuoa");

System.out.println(trie.search("zuoa"));

System.out.println(trie.prefixNumber("zuo"));

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值