KMP字符串匹配算法的JAVA实现
至于KMP算法的原理和它与普通的字符串匹配方式的区别,下次记起来再写
import java.io.*;
public class StringMatch{
public static void main(String[] args) {
StringMatch s = new StringMatch();
s.matchString("sdgsgsfabvadgsfsabcadgsfabcabcabcdd","a");
s.matchFile("Solution.java","tt");
}
public void matchString(String s, String p){
Handler handler = new StringHandler(s);
matchStringFromStart(s,0, p, handler);
}
public void matchFile(String file, String p){
BufferedReader bin = null;
try{
FileReader fileReader = new FileReader(new File(file));
bin = new BufferedReader(fileReader);
String s = null;
int line = 1;
while ((s = bin.readLine()) != null){
FileHandler fileHandler = new FileHandler(s,line);
matchStringFromStart(s,0,p,fileHandler);
++line;
}
}catch(IOException e){
e.printStackTrace();
}
try{
if (bin != null){
bin.close();
}
}catch(IOException e){
e.printStackTrace();
}
}
private void matchStringFromStart(String s,int sstart, String p, Handler handler){
if (s==null||s.length()==0) return;
int [] next = computeNext(p);
if (next == null) return;
int pstart = 0;
while(sstart < s.length() && pstart < p.length()){
if (pstart == -1 || s.charAt(sstart) == p.charAt(pstart)){
++sstart;
++pstart;
}else{
pstart = next[pstart];
}
}
if (pstart == p.length()) handler.handle(sstart - pstart, sstart);
if ((sstart - pstart) < s.length()-p.length()) matchStringFromStart(s, sstart - pstart + 1, p, handler);
}
protected int [] computeNext(String p){
if (p==null||p.length()==0) return null;
if (p.length() == 1) return new int []{-1};
int [] next = new int[p.length()];
next[0] = -1;
next[1] = 0;
for (int i = 2; i<next.length;++i){
int k = next[i-1];
while (k >= 0 && p.charAt(k)!=p.charAt(i-1)){
k = next[k];
}
next[i] = k + 1;
}
return next;
}
}
interface Handler{
public void handle(int start, int end);
}
class StringHandler implements Handler {
private String s;
StringHandler(String s){
this.s = s;
}
@Override
public void handle(int start, int end){
System.out.println("Starts at "+start);
}
}
class FileHandler implements Handler{
private String s;
private int line;
FileHandler(String s,int line){
this.s = s;
this.line = line;
}
@Override
public void handle(int start, int end){
System.out.println("At line "+line+". Starts at "+start);
}
}