字符串搜索子串的算法(KMP算法)

菲洛
比如在字符串s:"a a a b"中搜索t:“a a b”,

在比较s[2]!=t[2]后,下一次直接比较s[2]和t[1]是否相等,而不是从

s[1]和t[0]开始比较。即我们在第一次匹配中有部分信息有可能加

速我们的第二次匹配,第二次匹配没必要从t[0]开始比较。我们创

建一个长度为t.length的整数数组next,对于t中的每一个字符t[i],

next[i]表示字符t[i]之前有没有可以加速匹配的信息。具体表示是:

n e x t [ i ] = { m a x { k ∣ 0 &lt; k &lt; i , 且 &quot; t 0 t 1 . . . t k − 1 &quot; = &quot; t i − k t i − k + 1 . . . t i − 1 } − 1    当 i = 0 时 0         其 他 情 况 时 next[i]=\left\{ \begin{aligned} &amp;max\{k|0&lt;k&lt;i,且&quot;t_0t_1...t_{k-1}&quot;=&quot;t_{i-k}t_{i-k+1}...t_{i-1}\} \\ &amp;-1\ \ 当i=0时\\ &amp;0 \ \ \ \ \ \ \ 其他情况时 \end{aligned} \right. next[i]=max{k0<k<i,"t0t1...tk1"="tiktik+1...ti1}1  i=00       
(注意上面的max里面i-k是大于0的)

next[i]字面意思是t[i]前面最多有k(k<t.length)个元素与从头开始

的k个元素相等,所以当s[j]!=t[i]时,接着直接让s[j]与t[next[i]]作比

较(因为下标是从0开始,不是1),如果直到next[i]=-1,依然不相等,那么就比较s[j+1]与t[0](最坏情况)

获取next数组的办法:

public void getNext(String str,int[]next) {
		int j,k;
		j=0;k=-1;next[0]=-1;
		int len=str.length();
		while(j<len-1) {
			if(k==-1||str.charAt(j)==str.charAt(k)) {
				++j;++k;
				next[j]=k;
			}
			else k=next[k];	/*这里也是利用
			前面得到的next数组来加速循环过程*/
		}
	}

实际应用:题目

 public int strStr(String haystack, String needle) {
	        int len=needle.length();
	        int[]next=new int[len];
	        if(len==0)
	             return 0;
	        getNext(needle,next);
	        int i=0,j=0,len2=haystack.length();
	        while(i<len2) {
	        	if(j==-1||haystack.charAt(i)==needle.charAt(j)) {
	        		++j;
	        		++i;
	        		if(j==len) {
	        			return i-len;
	        		}
	        	}
	        	else {
	        		j=next[j];
	        	}
	        }
	        return -1;
	    }

时间复杂度:
设s长度为n, t的长度为m。
则 求next数组复杂度为O(m),因为在匹配过程中s的下标不会减少,比较次数是n,这个算法的平均时间复杂度为O(n+m)。
最坏的时间复杂度为O(n x m)。

到现在还没看懂的话,原谅我的理解和表达能力,可以先放下,

过段时间再去思考。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值