写在前面的话
一般情况下学习东西我们都会问自己What,Why,How这三个问题,同样我们也要知道什么是KMP为什么要用KMP怎么用KMP这三个问题!
What is KMP
KMP算法主要是用来做字符串匹配的,他和我们挨个挨个匹配的基础上改进而来的。举个例子,一般情况下加入有母串M1 M2 M3 M4 M5 M6 M7 M8 M9 M10有子串S1 S2 S3 S4一般情况下我们都是先那S1和M1匹配,若匹配则在匹配 S2 M2,否则匹配 S1 和 M1,加入子串没有别的特征这样做的话也是可以的,但当子串为abcdefabc的时候这样我们引入KMP可以大大节省时间。
Why Need KMP
比如说我们现在又母串ababcababa子串ababa,当我匹配成
时候!我们其实可以跳跃匹配,不要再从第二个重新匹配的,因为子串有对称串,KMP就是这样在一般匹配上改进的。
How KMP
在第二部分,我们知道了可以跳跃匹配,但是跳跃多少等等,就是我们接下来要解决的问题:
package kmp;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
String moduelString = "";//母串
String matchingString = "";//要去匹配的串
Scanner sc = new Scanner( System.in);
moduelString = sc.nextLine();
matchingString = sc.nextLine();
if(KMPMatch(moduelString, matchingString)==-1) System.out.println("不匹配");
else System.out.println("匹配");
if(moduelString.contains(matchingString)) System.out.println("contain");
}
public static int KMPMatch(String moduelString, String matchingString){
int flag = -1;
int i = 0;
int j = 0;
int[] next = new int[matchingString.length()];
getNext(matchingString, next);
while(i<moduelString.length()){
if(j==-1||moduelString.charAt(i)==matchingString.charAt(j))
{
i++;
j++;
}
else
{
j=next[j]; //消除了指针i的回溯
}
if(j== matchingString.length()) return i-j;
}
return flag;
}
public static void getNext(String matchingString,int[] next ){
next[0] = -1;
for (int i = 1; i < next.length; i++) next[i] = 0;
int j=0;
int k =-1;
while(j<matchingString.length()-1)
{
if(k==-1|| matchingString.charAt(j)== matchingString.charAt(k))//匹配的情况下,p[j]==p[k]
{
j++;
k++;
next[j]=k;
}
else //p[j]!=p[k]
k=next[k];
}
}
}