KMP算法用来计算文本串是否存在模式串,其主要思想是,通过对模式串进行处理产生前缀表,也称为next数组,来告知当模式串文本串在哪里不匹配时,模式串回退到何处与文本串不匹配位置继续匹配。
题目示例:
实现 strStr() 函数。
给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。
说明:
当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。
对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。
示例 1:
输入:haystack = “hello”, needle = “ll”
输出:2
示例 2:
输入:haystack = “aaaaa”, needle = “bba”
输出:-1
示例 3:
输入:haystack = “”, needle = “”
输出:0
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/implement-strstr
//kmp算法实现
class Solution {
public int strStr(String haystack, String needle) {
//如果模式串为空,则返回0
if(needle.length()==0){
return 0;
}
//创建next数组
int[] next = new int[needle.length()];
//对next数组进行初始化,即获取前缀表
getNext(next, needle);
int j = 0;
//遍历文本串
for(int i = 0; i<haystack.length();i++){
//如果文本串与模式串不匹配时,告知next[j-1]告知j需要回退到那个位置。
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-needle.length()+1);
}
}
return -1;
}
//获取前缀表
public void getNext(int[]next,String s){
int i = 1;
int len = s.length();
int j = 0;
//对前缀表进行初始化
next[0] = 0;
for(;i<len;i++){
//当模式串的字符不相等时
while(j>0 && s.charAt(i)!=s.charAt(j)){
j = next[j-1];
}
//当模式串的字符相等时
if(s.charAt(i)==s.charAt(j)){
j++;
}
//对next数组进行赋值
next[i] = j;
}
}
}