KMP算法 子串查找



子串的查找

  1. BF查找法   时间复杂度(on*m))

    abbaaaabaab

    I                  判断条件: ij相等  i++j++;

    aaba                          i = j

    J                              i=i-j+1;     j回退到开始

     

  2. KMP算法    时间复杂度(on+m))

    如果j 能自己回退到他该回退位置,i就不用回退,这样就大大提高了算法的时间复杂度

    next数组就刚好提供j的回退下标

     

    Si-j.....Si-1 =P0....Pj-1  (1)

    P0......Pk-1=Si-k...Si-1  (2)

    Si-k.....Si-1=Pj-k....pj-1  (3)

    由(2),(3)推出

    P0.....Pk-1=Pj-k....pj-1   (4)

     

    通过(4)的结论我知道了next的寻找方式

    1. 在匹配成功的子串中查找两个最长且相等的真子串,这两个真子串的要求如下:

        一个以子串的开头作为开头,另一个以匹配成功的最后一个字符作为结尾。

      a b c d a b c d a b a b c

      -10 0 0 0 1 2 3 4 5 6 1 2

      这就是next数组的寻找方式

      Next数组算法思想:         

      a b c d a b c d a b a b c          

      K     j   

      arr[k]arr[j]相等时j++i++

      不相等时:k回退到原来

    static int * GetNext(const char *sub)
    {
    	int lensub = strlen(sub);
    	int *next = (int *)malloc(lensub*sizeof(int));
    	assert(next != NULL);
    
    	next[0] = -1;
    	next[1] = 0;
    	int j = 1;
    	int k = 0;
    
    	while(j+1<lensub)
    	{
    		if((k==-1) || (sub[k]==sub[j]))
    		{
    			/*next[j+1] = k+1;
    			j++;
    			k++;*/
    			next[++j] = ++k;
    		}
    		else
    		{
    			k = next[k];//***********
    		}
    	}
    
    	return next;
    }
    
    找到next数组后,方法和BF相同就是i不回退就好了,j=next数组
    
    int KMP(const char *str,const char *sub,int pos)
    {//O(n+m)
    	assert(str!=NULL && sub!=NULL);
    	int lenstr = strlen(str);
    	int lensub = strlen(sub);
    	if(pos<0 || pos>=lenstr)
    	{
    		return -1;
    	}
    
    	//int next[10] = {0};//todo
    	int *next = GetNext(sub);
    
    	int i = pos;
    	int j = 0;
    
    	while(i<lenstr && j<lensub)
    	{
    		if(j==-1 || (str[i]==sub[j]))
    		{
    			i++;
    			j++;
    		}
    		else
    		{
    			//i不回退
    			j = next[j];
    		}
    	}
    
    	free(next);
    
    	if(j >= lensub)
    	{
    		return i-j;
    	}
    	else
    	{
    		return -1;
    	}
    }
    




猜你喜欢

转载自blog.csdn.net/YanJing1314/article/details/80007605