后缀树 - 多模式匹配

学习了 cracking code interview 18.8 之后的整理。

用后缀树(Suffix Trie)寻找长字符串S中所有出现的子串T 

原理: 如果T为S的子串, 那么T一定是S某个后缀的前缀(或本身); 后缀树的root必须为空

时间复杂度:构造树 O(ns^2)

                        查找  O(nt)


1. 后缀树类, 后缀树存了字符串S所有的后缀

public class SuffixTreeNode {
	// 当前root的孩子们
	// 若为英语小写字母,则最多有26个孩子
	HashMap<Character, SuffixTreeNode> children 
	       = new HashMap<Character, SuffixTreeNode>();
	
	char value; // 当前节点的值
	
	// 存该后缀出现的起始位置,即多模式查找的结果
	// exp: S = bibs, T = b, 则 节点b的 indexes = [0,3]
	ArrayList<Integer> indexes = new ArrayList<Integer>();
	
	public SuffixTreeNode(){}
	
	public void insertString(String s, int index){
		indexes.add(index);  // 添加当前index
		if(s != null && s.length() > 0){
			value = s.charAt(0);
			SuffixTreeNode child = null;
			// 若root已经有这个value的孩子了,则将后缀附加到这个子节点树上
			if(children.containsKey(value)){
				child = children.get(value);
			}else{
				child = new SuffixTreeNode();
				children.put(value, child);
			}
			String remainder = s.substring(1);
			// 递归添加后缀
			child.insertString(remainder, index);
			
		}
	}
	
	public ArrayList<Integer> search(String s){
		if(s == null || s.length() == 0)
			return indexes;
		else{
			char first = s.charAt(0);
			if(children.containsKey(first)){
				String remainder = s.substring(1);
				return children.get(first).search(remainder);
			}
		}
		return null;
	}
}

2. 构造S的后缀树 - O(ns^2)

public class SuffixTrie {
	// 后缀树的根节点必须为空
	SuffixTreeNode root = new SuffixTreeNode();
	// 构造S的后缀树
	public SuffixTrie(String s){
		for(int i = 0; i < s.length(); i++){
			String suffix = s.substring(i);
			root.insertString(suffix, i);
		}
	}
	public ArrayList<Character> search(String t){
		return root.search(t);
	}
}

3. 使用后缀树查找


public ArrayList<Integer> findSubStr(String s, String t){
		SuffixTrie trie = new SuffixTrie(s);
		return trie.search(t);
	}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值