高效的字符串匹配器

高效的字符串匹配器

使用场景

String html="......<script type="text/javascript.........</script>"";

StringMatcher matcher = new StringMatcher("</script>");


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

    matcher.push(html.charAt(i));

    if(matcher.isTarget()){

        //do something

    }

}
/**
 * StringMathcer是一个利用了循环链表原理的数组型字符串匹配器.
 * 
 * Matcher主要是在字符串处理中匹配字串,原理是把字符push到匹配器中 进行比较,匹配器不提供remove(int index)方法,只能放或者清空。
 * 用单纯的数组进行匹配时,很容易地,数组会满而导致大量的元素移动操作, 代价交代,用循环链表只需修改两次指针位置即可。
 * 为了更多的减少条件判断,在构造方法中就已经让数组处于满的状态。
 * 
 * @author maoanapex88@163.com
 * 
 */
public class StringMatcher {
	char[] cache;
	int start;
	String target;

	public StringMatcher(String s) {
		this.target = s;
		int length = s.length();
		cache = new char[length];
		start = 0;
		for (int i = 0; i < cache.length; i++)
			cache[i] = 128;
	}

	public void push(char c) {
		cache[start++] = c;
		start %= cache.length;
	}

	public boolean isTarget() {
		if (cache[(start + 1) % cache.length] == 128)
			return false;
		int index = 0;
		for (int i = start; i < cache.length; i++, index++)
			if (cache[i] != target.charAt(index))
				return false;
		for (int i = 0; i < start; i++, index++)
			if (cache[i] != target.charAt(index))
				return false;
		return true;
	}

	public boolean isTarget(boolean ignoreCase) {
		if (cache[(start + 1) % cache.length] == 128)
			return false;
		int index = 0;
		for (int i = start; i < cache.length; i++, index++) {
			if (ignoreCase && cache[i] != target.charAt(index)
					&& cache[i] - target.charAt(index) != 32
					&& cache[i] - target.charAt(index) != -32)
				return false;
		}
		for (int i = 0; i < start; i++, index++) {
			if (ignoreCase && cache[i] != target.charAt(index)
					&& cache[i] - target.charAt(index) != 32
					&& cache[i] - target.charAt(index) != -32)
				return false;
		}
		return true;
	}

	/**
	 * clear
	 */
	public void clear() {
		start = 0;
		for (int i = 0; i < cache.length; i++)
			cache[i] = 128;
	}

	/**
	 * @return
	 */
	public int length() {
		return target.length();
	}
}

发表评论

您的电子邮箱地址不会被公开。