前缀树

但是要判断字符串是否已经加过:
在节点还保存一个信息:是否以这个节点为结尾?计数(加入几次这个字符串)。

如果问:给一个字符串,有多少字符串以它作为前缀?
解决方法:加一个数据项(每一个节点被划过多少次)

前缀树:代价极低!效率非常高,和样本量没关系,和自身样本长度有关。

TrieNode代码:

public static class TrieNode{
    public int path; //经过多少次
    public int end;  //以该节点结尾的的字符串有几个
    public TrieNode[] next;
    public TrieNode(){
        path = 0;
        end = 0;
        next = neww TrieNode[26]; //a-z 26条可能路径;如果其他的用map来做路径
    }
}

Trie前缀树:

public static class Trie{
    private TrieNode root;
    public Trie(){
        root = new TrieNode();
    }
    public void insert(String word){
        if(word==null){
            return null;
        }
        char[] chs = word.toCharArray();
        TrieNode node = root;
        int index = 0;
        for(int i = 0; i<chs.length;i++){
            index = chs[i] - 'a';
            if(node.nexts[index]==null){
                node.nexts[index]=new TrieNode();
            }
            node = node.nexts[index];
            node.path++;
        }
        node.end++;
    }
}

查询:

public int search(String word){
    if(word==null){
        return 0;
    }
    char[] chs = word.toCharArray();
    TrieNode node = root;
    int index = 0 ;
    for(int i = 0; i<chs.length;i++){
		index = chs[i] - 'a';
		if(node.nexts[index]==null){
			return 0;    //没有插入过,返回0
	    }
        node = node.nexts[index];
    }
    return node.end;
}

删除:

public void delete(String word){
    if(search(word)!=0){
        char[] chs = word.toCharArray();
	    TrieNode node = root;
	    int index = 0;
        for(int i = 0; i<chs.length;i++){
		    index = chs[i] - 'a';
		    if(--node.nexts[index].path==0){
                node.nexts[index]=null;//之后不需要沿途减了,底下直接为空,JVM可以释放,C++的话还得找到以下的节点,析构
		    	return 0;    
		    }
		    node = node.nexts[index];
	    }
        node.end--;
    }
}

查找前缀的数目

public int preixNumber(String pre){
    if(pre==null){
        return 0;
    }
    char[] chs = pre.toCharArray();
    TrieNode node = root;
    int index = 0;
    for(int i = 0; i<chs.length;i++){
		index = chs[i] - 'a';
		if(node.nexts[index]==null){
			return 0;    
		}
		node = node.nexts[index];
	}
    return node.path;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值