KMP算法记住一句话:构造最大长度后缀数组
1. 根据当前的next[j] = k; 进而推断next[j+1] = ?; 思想是:如果当前P(j) == P(k), 就把最长后缀伸长一点;否则区间变小。
2.KMP是和getNext(); similar
3.记住那句话:构造最大长度后缀
4.对getNext();优化
import java.io.*;
public class Test
{
public static void main(String args[]) throws IOException
{
BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));
String str1 = buf.readLine();
String str2 = buf.readLine();
KMP(str1, str2);
}
// getNext();
public static int[] getNext(char x[])
{
int next[] = new int[x.length];
next[0] = -1;
int i = 0;
int j = -1;
while (i < next.length - 1) // take care
{
if (j == -1 || x[i] == x[j])
{
++i;
++j; // ++i, ++j, 表明最长后缀伸长
next[i] = j;
}
else
{
j = next[j];
}
}
return next;
}
// KMP
public static void KMP(String t, String p)
{
char ch[] = p.toCharArray();
int next[] = getNext(ch);
int i = 0;
int j = 0;
while (i < t.length() && j <p.length())
{
if (j == -1 || t.charAt(i) == p.charAt(j))
{
++i;
++j;
}
else
{
j = next[j];
}
}
if (j == p.length())
System.out.println(i - p.length());
else
System.out.println("no");
}
}
修正next【】的结果:
public static int[] getNext(char x[])
{
int next[] = new int[x.length];
next[0] = -1;
int i = 0;
int j = -1;
while (i < next.length - 1) // take care
{
if (j == -1 || x[i] == x[j])
{
++i;
++j;
if (x[i] == x[j])
next[i] = next[j];
else
next[i] = j;
}
else
{
j = next[j];
}
}
return next;
}