Created
February 8, 2017 06:38
-
-
Save jianminchen/0ca0a5ebae137e41af1094653bad793d to your computer and use it in GitHub Desktop.
Rabin-karp algorithm - need to work on the algorithm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Numerics; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace HackerRank_hiddenMessage | |
{ | |
/** | |
source code: | |
http://algs4.cs.princeton.edu/code/edu/princeton/cs/algs4/RabinKarp.java.html | |
*/ | |
public class RabinKarp | |
{ | |
private String pat; // the pattern // needed only for Las Vegas | |
private long patHash; // pattern hash value | |
private int m; // pattern length | |
private long q; // a large prime, small enough to avoid long overflow | |
private int R; // radix | |
private long RM; // R^(M-1) % Q | |
/** | |
* Preprocesses the pattern string. | |
* | |
* @param pattern the pattern string | |
* @param R the alphabet size | |
*/ | |
public RabinKarp(char[] pattern, int R) | |
{ | |
this.pat = new string(pattern); | |
this.R = R; | |
} | |
/** | |
* Preprocesses the pattern string. | |
* | |
* @param pat the pattern string | |
*/ | |
public RabinKarp(String pat) | |
{ | |
this.pat = pat; // save pattern (needed only for Las Vegas) | |
R = 256; | |
m = pat.Length; | |
q = LongRandomPrime(); | |
// precompute R^(m-1) % q for use in removing leading digit | |
RM = 1; | |
for (int i = 1; i <= m - 1; i++) | |
{ | |
RM = (R * RM) % q; | |
} | |
patHash = hash(pat, m); | |
} | |
// Compute hash for key[0..m-1]. | |
private long hash(String key, int m) | |
{ | |
long h = 0; | |
for (int j = 0; j < m; j++) | |
{ | |
h = (R * h + key[j]) % q; | |
} | |
return h; | |
} | |
// Las Vegas version: does pat[] match text[i..i-m+1] ? | |
private bool Check(String text, int i) | |
{ | |
for (int j = 0; j < m; j++) | |
{ | |
if (pat[j] != text[i + j]) | |
{ | |
return false; | |
} | |
} | |
return true; | |
} | |
// Monte Carlo version: always return true | |
// private boolean check(int i) { | |
// return true; | |
//} | |
/** | |
* Returns the index of the first occurrrence of the pattern string | |
* in the text string. | |
* | |
* @param txt the text string | |
* @return the index of the first occurrence of the pattern string | |
* in the text string; n if no such match | |
*/ | |
public int Search(String text) | |
{ | |
int n = text.Length; | |
if (n < m) return n; | |
long txtHash = hash(text, m); | |
// check for match at offset 0 | |
if ((patHash == txtHash) && Check(text, 0)) | |
{ | |
return 0; | |
} | |
// check for hash match; if hash match, check for exact match | |
for (int i = m; i < n; i++) | |
{ | |
// Remove leading digit, add trailing digit, check for match. | |
txtHash = (txtHash + q - RM * text[i - m] % q) % q; | |
txtHash = (txtHash * R + text[i]) % q; | |
// match | |
int offset = i - m + 1; | |
if ((patHash == txtHash) && Check(text, offset)) | |
{ | |
return offset; | |
} | |
} | |
// no match | |
return n; | |
} | |
// a random 31-bit prime | |
private static long LongRandomPrime() | |
{ | |
//BigInteger prime = BigInteger.probablePrime(31, new Random()); | |
BigInteger prime = BigInteger.probablePrime(31, new Random()); | |
return prime.longValue(); | |
} | |
/** | |
* Takes a pattern string and an input string as command-line arguments; | |
* searches for the pattern string in the text string; and prints | |
* the first occurrence of the pattern string in the text string. | |
* | |
* @param args the command-line arguments | |
*/ | |
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 | |
Console.WriteLine("text: " + txt); | |
// from brute force search method 1 | |
Console.WriteLine("pattern: "); | |
for (int i = 0; i < offset; i++) | |
{ | |
Console.WriteLine(" "); | |
} | |
Console.WriteLine(pat); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment