kmp算法初识

来源:互联网 发布:雷锋源越狱软件 编辑:程序博客网 时间:2024/06/15 19:49

这个算法的确是不好理解,这是令人头疼,所以这里我先把一些大佬的文章贴在这里,等我彻底理解了,我在回来补充

这个文章可以说是非常清楚了:

http://blog.csdn.net/v_july_v/article/details/7041827

下面我在补充上一道我遇到的题:

14184646038225.jpg

fjxmlhx不喜欢网上的 marshtomps 。所以他决定把所有的“marshtomp”(名字不区分大小写)改为 “fjxmlhx;

Input

输入包含多行,每行字符串不超过200的长度,一个单词不会一半出现在上一行,剩下的在下一行。直到文件结束(EOF)

Output

输出 替换之后的字符串。

Sample Input
The Marshtomp has seen it all before.marshTomp is beaten by fjxmlhx!AmarshtompB
Sample Output
The fjxmlhx has seen it all before.fjxmlhx is beaten by fjxmlhx!AfjxmlhxB
代码如下:

import java.util.*;public class Main {    static ArrayList<Integer> find(String s, String pattern) {        ArrayList<Integer> st = new ArrayList<Integer>();//用来存放找到了的字符串的开始索引        int[] next = new int[pattern.length()];        getNext(pattern, next);
        int i = 0; 
int j = 0;
 while (i < s.length() ) {
  if (j == -1 || s.charAt(i) == pattern.charAt(j)) {
i++; j++;
}
 else {
  j = next[j];
}
if (j == pattern.length()) {
st.add(i - pattern.length()); j = 0;//找到了一个,继续从头开始,因为是一行文字,可能有多个匹配
  }
  }
return st;
 }
static void getNext(String str, int[] next) {
 next[0] = -1;
int j = -1;
int i = 0;
while (i < str.length() - 1) {
 if ( j == -1 || str.charAt(i) == str.charAt(j) ) {
 i++; j++;
next[i] = j;
}
else
{ j = next[j];
 }
 }
 }
 static Scanner in = new Scanner(System.in);
 public static void main(String[] args) {
while (in.hasNext()) {
 String s = in.nextLine();
 ArrayList<Integer> indexSet = find(s.toLowerCase(), "marshtomp");
 StringBuilder sb = new StringBuilder();
int startIndex = 0;
 indexSet.add(s.length());//这里讲s的长度加进去的目的是,为了方便将匹配替换之后的字符串进行拼接形成完整的句子
          //比如,The Marshtomp has seen it all before.,替换之后,为了将 has seen it all before.,拼接上,(因为用到了substring)但是同时最后会多一个
//fjxmlhx,所以最后删除一下
  for (int i = 0; i < indexSet.size(); i++) {
//通过拼接形成替换之后的一行句子,遇到目标后,从开始一直到匹配到索引位置,将替换的字符串添加上,就这样不断拼接下去

  sb.append(s.substring(startIndex, indexSet.get(i))).append("fjxmlhx");
startIndex = indexSet.get(i) + 9; //跳过这个被替换的字符串
 }
sb.delete(sb.length()-7, sb.length());//将最后为了拼接完整的句子而添加的多余的fjxmlhx删除
 System.out.println(sb.toString());
 }
}
}