# 导航

2 6 5 3 6 % 997 = 613

3 1 4 1 5 % 997 = 508

1 4 1 5 9 % 997 = 201

......

2 6 5 3 6 % 997 = 613 (匹配)

2 % 997 = 2

2 6 % 997 = (2*10 + 6) % 997 = 26

2 6 5 % 997 = (26*10 + 5) % 997 = 265

2 6 5 3 % 997 = (265*10 + 3) % 997 = 659

2 6 5 3 5 % 997 = (659*10 + 5) % 997 = 613

3 1 4 1 5 9 2 6 5 3 5 8 9 7 9 3

3 % 997 = 3

3 1 % 997 = (3*10 + 1) %997 = 31

3 1 4 % 997 = (31*10 + 4) % 997 = 314

3 1 4 1 % 997 = (314*10 + 1) % 997 = 150

3 1 4 1 5 % 997 = (150*10 + 5) % 997 = 508

1 4 1 5 9 % 997 = ( (508 + 3*(997 - 30) ) *10 + 9) % 997 = 201

4 1 5 9 2 % 997 = ( (201 + 1*(997 - 30) ) *10 + 2) % 997 = 715

......

2 6 5 3 6 % 997 =  ( (929 + 9*(997 - 30) ) *10 + 5) % 997 = 613

import java.math.BigInteger;
import java.util.Random;

import edu.princeton.cs.algs4.StdOut;

public class RabinKarp {
private String pat;    //模式字符串
private long patHash;    //模式字符串散列值
private int M;     //模式字符串的长度
private long Q;    //很大的素数
private int R;    //字母表的大小
private long RM;    //R^(M-1) % Q

public RabinKarp(char[] pat, int R){
this.pat = String.valueOf(pat);
this.R = R;
}

public RabinKarp(String pat){
this.pat = pat;
R = 256;
M = pat.length();
Q = longRandomPrime();

RM = 1;
for(int i=1; i<=M-1; i++){
RM = (R * RM) % Q;
}
patHash = hash(pat, M);
}

private long hash(String str, int M){
long h = 0;
for(int i=0; i < M; i++){
h = (R * h + str.charAt(i)) % Q;
}
return h;
}

public boolean check(String txt,int i){
for(int j = 0; j < M; j++){
if(pat.charAt(j) != txt.charAt(i+j))
return false;
}
return true;
}

private static long longRandomPrime() {
BigInteger prime = BigInteger.probablePrime(31, new Random());
return prime.longValue();
}

private int search(String txt){
int N = txt.length();
if(N < M) return N;
long txtHash = hash(txt,M);

if((txtHash == patHash) && check(txt, 0)) return 0;
for(int i = M; i < N; i++){
txtHash = (txtHash + Q - RM*txt.charAt(i-M) % Q) % Q;
txtHash = (txtHash*R + txt.charAt(i)) % Q;
int offset = i-M+1;
if((patHash == txtHash) && check(txt, offset))
return offset;
}
return N;
}

public static void main(String[] args) {
String pat = args[0];
String txt = args[1];

RabinKarp searcher = new RabinKarp(pat);
int offset = searcher.search(txt);
// print results
StdOut.println("text:    " + txt);

// from brute force search method 1
StdOut.print("pattern: ");
for (int i = 0; i < offset; i++)
StdOut.print(" ");
StdOut.println(pat);
}
}
View Code

posted on 2016-11-09 22:48  谭兄  阅读(2496)  评论(0编辑  收藏  举报