002字符串查找---KMP算法

本文参考《算法(第4版)》

1.暴力字符串查找算法

子字符串查找的最显而易见的方法就是在文本模式中任何可能发生匹配的地方检查匹配是否存在。
暴力字符串查找算法是一种子字符串查找算法,是模式字符串在文本字符串中逐个字符进行比较。
search()方式使用一个指针 i 跟踪文本字符串,使用一个指针 j 跟踪跟踪模式字符串。
假定从左到右方向比较字符串,文本指针和模式指针起始比较位置都为0,当文本字符和模式字符匹配时,则模式指针向右移动一位,继续和文本字符串的下一位进行比较。
匹配失败时,文本指针 i 右移一位,同时模式指针 j 回退到模式字符串的起始位置,再进行下一轮比较,直到找到一个不匹配的字符或者模式结束于j == M
该方法中发生模式不匹配时,文本指标和模式指针都需要回退。由于绝大时候不匹配发生在第一个字符,所以模式指针 j 的增长机会很少,算法的时间复杂度和文本字符串长度N成正比。
在最坏的情况下暴力字符串查找算法在长度为N的文本字符串中查找长度为M的模式字符串所需要的比较次数和NM成正比。
search2()方法是暴力字符串查找算法的另一种实现。
实现代码:

package subStringSearch; 
public class ForceSearch {
    public static int search(String pat, String txt){
    	int M = pat.length();
    	int N = txt.length(); 
    	for(int i = 0; i <= N - M; i++){
    		int j;
    		for(j = 0; j < M; j++)
    			if(pat.charAt(j)!=txt.charAt(i+j)) 
    				break; 
    	    if(j == M) return i; 		
    	}  
    	return N;
    }
    public static int search2(String pat, String txt){
    	int M = pat.length();
    	int N = txt.length(); 
    	int j = 0;
    	for(int i = 0; i < N; i++){
    		if(pat.charAt(j) == txt.charAt(j))  j++;
    		else{ i -= j; j = 0;}
    		if(j == M) return i - M;
    	}
        return N;
    }
	public static void main(String[] args) {
		String pat = "abcd";
		String txt = "adsedsabcdeabcdf";
		int index = search(pat, txt);
        System.out.println(index);
        System.out.println(txt.substring(index, index+pat.length()));
        
        int index2 = search(pat, txt);
        System.out.println(index2);
        System.out.println(txt.substring(index, index2+pat.length()));
	}
}

输出:

6
abcd
6
abcd

2.KMP算法

package subStringSearch; 
public class KMP {
    private String pat; 
    private int[][] dfa;
    public KMP(String pat){
    	this.pat = pat;
    	int M = pat.length();
    	int R = 256;
    	dfa = new int[R][M];
    	dfa[pat.charAt(0)][0] = 1;
    	for(int X = 0, j = 1; j < M; j++){
    		for(int c = 0; c < R; c++)
    		    dfa[c][j] = dfa[c][X];     //复制匹配失败情况下的值
    		dfa[pat.charAt(j)][j] = j + 1; //设置匹配成功情况下的值
    		X = dfa[pat.charAt(j)][X];     //更新重启状态
    	}  
    }
    public int search(String txt){
		int i, j, N = txt.length(), M = pat.length(); 
		for(i = 0, j = 0; i < N && j < M; i++) 
			j = dfa[txt.charAt(i)][j];
		if(j == M) return i - M; 
		else       return N;
	}
	public static void main(String[] args) {
		String pat = "abcd";
		String txt = "adsedsabcdeabcdf";
		KMP kmp = new KMP(pat);
		int index = kmp.search(txt);
        System.out.println(index);
        System.out.println(txt.substring(index, index+pat.length()));
	}
}

输出:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值