(代码如有错误,烦请指正)
把字符串列表的字符串挂在树上,一般把字符建在路上,已经出现的字符可以复用。
//只适用于26字母
class Node{
int pass;//记录经过该节点的字符串个数
int end;//记录以该节点作为结尾的字符串的个数
Node[] nexts;
public Node(){
pass=0;
end=0;
nexts=new Node[26];
}
}
class TrieTree{
//新建一个前缀树,就会初始化一个根节点
Node root;
public TrieTree(){
Node root=new Node();
}
//插入一个字符串
public void insert(String str){
if(str==null){
return;
}
char[] c=str.toCharArray();//将字符串切分成字符数组
root.pass++;//因为所有数组都会经过根节点
Node cur=root;
int path=0;
for(int i=0;i<c.length;i++){
path=c[i]-'a';//根据字符确定走哪一条路
if(cur.nexts[path]==null){
cur.nexts[path]=new Node();//该字符所在的节点不在则创建
}
cur=cur.nexts[path];//当前节点向下走
cur.pass++;
}
cur.end++;
}
//确定该前缀树加入某一个字符串的次数
public int searchNum(String str){
if(str==null){
return 0;
}
char[] c=str.toCharArray();
Node cur=root;
int path=0;
for(int i=0;i<c.length;i++){
path=c[i]-'a';
if(cur.nexts[path]==null){
return 0;//说明该字符串的路径不存在,即没有加入过该字符串
}
cur=cur.nexts[path];
}
return cur.end;
}
//删除前缀树中的一个字符串
public void delete(String str){
if(searchNum(str)==0){
return;
}else{
char[] c=str.toCharArray();
Node cur=root;
cur.pass--;
int path=0;
for(int i=0;i<c.length;i++){
path=c[i]-'a';
if(--cur.nexts[path].pass==0){//判断删除该字符串自否会导致某些节点删除
cur.nexts[path]=null;//该节点后的内容均清除,然后返回
return;
}
cur=cur.nexts[path];
}
cur.end--;
}
}
// 所有加入的字符串中,有几个是以pre这个字符串作为前缀的
public int preSearchNum(String pre){
if(pre==null){
return 0;
}
char[] c=pre.toCharArray();
Node cur=root;
int path=0;
for(int i=0;i<c.length;i++){
path=c[i]='a';
if(cur.nexts[path]==null){
return 0;
}
cur=cur.nexts[path];
}
return cur.pass;
}
}
//适用于多种字符
class Node2{
int pass;
int end;
HashMap<Integer,Node2> nexts;
public Node2(){
pass=0;
end=0;
nexts=new HashMap<>();
}
}
class TrieTree2{
Node2 root;
public TrieTree2(){
root=new Node2();
}
//插入一个字符串
public void insert(String str){
if(str==null){
return;
}
char[] c=str.toCharArray();
Node2 cur=root;
cur.pass++;
int path=0;
for(int i=0;i<c.length;i++){
path=(int)c[i];
if(!cur.nexts.containsKey(path)){
Node2 node=new Node2();
cur.nexts.put(path,node);//不存在则新建
}
cur=cur.nexts.get(path);
cur.pass++;
}
cur.end++;
}
//判断一个字符加入过几次
public int searchNum(String str){
if(str==null){
return 0;
}
Node2 cur=root;
char[] c=str.toCharArray();
int path=0;
for(int i=0;i<c.length;i++){
path=(int)c[i];
if(!cur.nexts.containsKey(path)){
return 0;
}
cur=cur.nexts.get(path);
}
return cur.end;
}
//删除一个字符串
public void delete(String str){
if(searchNum(str)<1){
return;
}else{
Node2 cur=root;
cur.pass--;
char[] c=str.toCharArray();
int path=0;
for(int i=0;i<c.length;i++){
path=(int)c[i];
if(--cur.nexts.get(path).pass==0){
cur.nexts.remove(path);//不一样的地方
return;
}
cur=cur.nexts.get(path);
}
cur.end--;
}
}
//查询以pre作为前缀的字符串加入了几个
public int searchPreNum(String pre){
if(pre==null){
return 0;
}
Node2 cur=root;
char[] c=pre.toCharArray();
int path=0;
for(int i=0;i<c.length;i++){
path=(int)c[i];
if(cur.nexts.get(path)==null){
return 0;
}
cur=cur.nexts.get(path);
}
return cur.pass;
}