求最长公共前缀和后缀—基于KMP的next数组

KMP算法最主要的就是计算next[]算法,但是我们知道next[]求的是当前字符串之前的子字符串的最大前后缀数,但是有的时候我们需要比较字符串中前后缀最大数,比如

LeetCode的shortest Palindrome 就是基于KMP算法求最短子字符串。

 

public static int[] longestPS(String s) {
		int sLen = s.length();
		char[] p = s.toCharArray();
		//存放最大前缀后缀数
		int[] lNext = new int[sLen];
		//最大前后缀数(前缀指针)
		int k = 0;
		//后缀指针
		int j = 1;
		
        while(j < sLen) {
            if(p[k] == p[j]) {
            	//相等则将前一次比较的结果加上这次:k+1;然后继续加1比较。
            	lNext[j] = k + 1;
                k++;  j++;
            } else {
            	//如果p[k] != p[j]则k是不是在初始位置,是的话,K不变,后缀指针加1;
                if(k == 0) {
                	j++;
                } else { 
                	//k不为0,说明指针不在初始位置。根据lNext数组,找到上一个最大前后缀数的位置,继续判断。
                	k = lNext[k-1];
                }
            }
        }
        
        return lNext;
	}
/*
 * 举例:字符串 ABDABCE 
 * 对应的lNext == {0,0,0,1,2,0,0};
 * 
 */


下面是KMP的next数组代码,用以比较。

 

 

public void GetNext(char* p,int next[]) {  
	int pLen = strlen(p);  
	next[0] = -1;  
	int k = -1;  
	int j = 0;  
	while (j < pLen - 1)  {   
	   if (k == -1 || p[j] == p[k]) {  
           ++k;  
           ++j;  
           next[j] = k;  
        } else {  
            k = next[k];  
          }  
   }  
} 

如果想要更详细的学习KMP算法,建议请移步此篇博客,从头到尾彻底理解KMP,这是我学习中收收获最多的。

 

posted @ 2017-06-11 14:51  傍晚的羔羊  阅读(1580)  评论(0编辑  收藏  举报