KMP算法之Implement strStr()

Topic: Hard Mode

Question:

Implement strStr().

Returns a pointer to the first occurrence of needle in haystack, or null if needle is not part of haystack.

» Solve this problem


方法:

简单的办法是两层循环,一个大循环,一个小循环,如果小循环的范围内不能匹配,那么大循环从小循环的起始位置下一个重新遍历。

另一种方法:KMP,很复杂的算法。计算needle的覆盖率,然后循环结合覆盖率可以使大循环不用重新返回的多与步骤。

参考:http://blog.csdn.net/v_july_v/article/details/6111565


Code:

class Test{
    public static void main(String[] args){	
		String s1 = "cdeababcfgcabcz";
		String s2 = "abc";
		KmpString ks = new KmpString();
		
		//求第一个s2在s1中出现的位置
		System.out.println(ks.norStr(s1, s2));
		System.out.println(ks.kmpStr(s1, s2));
	}	
}

class KmpString{
	//简单算法
	public int norStr(String s1, String s2){
		int res = -1;
		if(s1.length() < s2.length()) return -1;
		for(int i=0; i<s1.length()+1-s2.length(); i++){
			if(s1.charAt(i) == s2.charAt(0)){
				res = check(s1, s2, i);
				if(res == -1) continue;
				else return res;
			}
		}
		return res;
	}
	private int check(String s1, String s2, int index){
		for(int i=0; i<s2.length(); i++)
			if(s1.charAt(index+i) != s2.charAt(i))
				return -1;
		return index;
	}
	
	//KMP算法
	public int kmpStr(String target, String pattern){
		int[] overLay = iniOverLay(pattern);
		int t = 0, p = 0;
		while(t<target.length() && p<pattern.length()){
			if(target.charAt(t) == pattern.charAt(p)){
				t++;
				p++;
			}
			else if(p == 0) t++;
			else p = overLay[p-1]+1;
		}
		if(p == pattern.length()) return t-p;
		else return -1;
	}
	private int[] iniOverLay(String pattern){
		char[] pat = pattern.toCharArray();
		int[] overLay = new int[pat.length];
		int index = -1;
		overLay[0] = -1;
		for(int i=1; i<pat.length; i++){
			index = overLay[i-1];
			while(index>=0 && pat[index+1]!=pat[i])
				index = overLay[index];
			if(pat[index+1] == pat[i])
				overLay[i] = index + 1;
			else
				overLay[i] = -1;
		}
		return overLay;
	}
}

Code.2 Leetcode之Implement strStr() 

public class Solution {
    public String strStr(String haystack, String needle) {
        // Start typing your Java solution below
        // DO NOT write main() function
        if(needle.length()==0) return haystack;
        
        int[] overLay = getOverLay(needle);
        int big = 0, small = 0;
        while(big<haystack.length() && small<needle.length()){
            if(haystack.charAt(big)==needle.charAt(small)){
                big++;
                small++;
            }
            else if(small == 0) big++;
            else small = overLay[small-1]+1;
        }
        if(small==needle.length()) return haystack.substring(big-small);
        else return null;
    }
    private int[] getOverLay(String needle){
        char[] pat = needle.toCharArray();
        int[] overLay = new int[pat.length];
        overLay[0] = -1;
        int index = -1;
        for(int i=1; i<pat.length; i++){
            index = overLay[i-1];
            while(index>=0 && pat[index+1]!=pat[i])
                index = overLay[index];
            if(pat[i] == pat[index+1])
                overLay[i] = index+1;
            else
                overLay[i] = -1;
        }
        return overLay;
    }
}


小结:

我们拿第二个KMP算法来解释,index的意义是当前所在“序列”的当前位置出现在needle的第一个位置的数值。好吧。

另一个难点是while循环(求overLay的while),他的目的是让index回到上一个(更彻底的说是第一个)所出现的位置。

最后,

else small = overLay[small-1]+1;

这句话的意思是needle的指针small指向上needle中上一个当前元素的位置,其实,等同于small=overLay[small]但是防止返回为零,所以改变了写法,另外结合这句的上一个判断条件就不难理解。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值