KMP算法主要用于判断一个文本串中是否包含另一个模式串,可以返回boolean以及匹配的模式串在文本串中首字母的下标。具体的原理我在此就不赘述了,直接来一套标准模板,以后按这个写就行。
1.首先要根据pattern模式串得到对应的next数组
代码如下:
/**
* 求解NEXT数组的方法
* @param s
* @return
*/
public int[] getNext(String s) {
int[] ans = new int[s.length()];
int j = 0;
for (int i = 1; i < s.length(); i++) {
while (j > 0 && s.charAt(j) != s.charAt(i)) j = ans[j - 1];
if (s.charAt(j) == s.charAt(i)) j++;
ans[i] = j;
}
return ans;
}
emm说实话KMP算法要根据next数组去匹配,我懂,就是这个next数组的生成我没太懂。。。不过问题不大,记住就行
2.接下来就是简单的判断text串中是否包含pattern串,代码:
/**
* 确立好的判断是否包含的KMP算法
* @param text
* @param pattern
* @return
*/
public boolean isInclude(String text, String pattern) {
int[] next = getNext(pattern);
int j = 0;
for (int i = 0; i < text.length(); i++) {
while (j > 0 && text.charAt(i) != pattern.charAt(j)) j = next[j - 1];
if (text.charAt(i) == pattern.charAt(j)) j++;
if (j == pattern.length()) return true;
}
return false;
}
3.判断text串中是否包含pattern串,并返回pattern串在text串中代码首字母匹配的下标:
/**
* 确立好了KMP模板,以后就按照这个写
* @param text
* @param pattern
* @return
*/
public int indexOf(String text, String pattern) {
if (pattern.length() < 1) return 0;
int[] next = getNext(pattern);
int j = 0;
for (int i = 0; i < text.length(); i++) {
while (j > 0 && text.charAt(i) != pattern.charAt(j)) j = next[j - 1];
if (text.charAt(i) == pattern.charAt(j)) j++;
if (j == pattern.length()) return i - pattern.length() + 1;//因为此时i还没有前移一位
}
return -1;
}
具体运用KMP算法的题目有:
解题代码如下,就是将上文中两个代码块组合在一起:
class Solution {
public int strStr(String haystack, String needle) {
if (needle.length() < 1) return 0;
int[] next = getNext(needle);
int j = 0;
for (int i = 0; i < haystack.length(); i++) {
while (j > 0 && haystack.charAt(i) != needle.charAt(j)) j = next[j - 1];
if (haystack.charAt(i) == needle.charAt(j)) j++;
if (j == needle.length()) return i + 1 - needle.length();
}
return -1;
}
private int[] getNext(String needle) {
int[] ans = new int[needle.length()];
int j = 0;
for (int i = 1; i < needle.length(); i++) {
while(j > 0 && needle.charAt(i) != needle.charAt(j)) j = ans[j - 1];
if (needle.charAt(i) == needle.charAt(j)) j++;
ans[i] = j;
}
return ans;
}
}
这道题目其实还是有点难的,有运用KMP算法比较强但是要好好理解的代码,有普通思路的代码(还没看)。。,先写上利用KMP求解的代码吧:
class Solution {
public boolean repeatedSubstringPattern(String s) {
if (s.length() < 1) return false;
int[] next = getNext(s);
if (next[next.length - 1] != 0 && s.length() % (s.length() - next[next.length - 1]) == 0) return true;
return false;
}
private int[] getNext(String pattern) {
int[] next = new int[pattern.length()];
int j = 0;
for (int i = 1; i < pattern.length(); i++) {
while (j > 0 && pattern.charAt(i) != pattern.charAt(j)) j = next[j - 1];
if (pattern.charAt(i) == pattern.charAt(j)) j++;
next[i] = j;
}
return next;
}
}