package com.interview.string; /** * Date 09/25/2014 * @author Tushar Roy * * Rabin Karp algorith for substring matching. * * Time complexity in worst case O(n^2)(depends on hash function) * Space complexity O(1) * * References * https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm */ public class RabinKarpSearch { private int prime = 101; public int patternSearch(char[] text, char[] pattern){ int m = pattern.length; int n = text.length; long patternHash = createHash(pattern, m - 1); long textHash = createHash(text, m - 1); for (int i = 1; i <= n - m + 1; i++) { if(patternHash == textHash && checkEqual(text, i - 1, i + m - 2, pattern, 0, m - 1)) { return i - 1; } if(i < n - m + 1) { textHash = recalculateHash(text, i - 1, i + m - 1, textHash, m); } } return -1; } private long recalculateHash(char[] str,int oldIndex, int newIndex,long oldHash, int patternLen) { long newHash = oldHash - str[oldIndex]; newHash = newHash/prime; newHash += str[newIndex]*Math.pow(prime, patternLen - 1); return newHash; } private long createHash(char[] str, int end){ long hash = 0; for (int i = 0 ; i <= end; i++) { hash += str[i]*Math.pow(prime,i); } return hash; } private boolean checkEqual(char str1[],int start1,int end1, char str2[],int start2,int end2){ if(end1 - start1 != end2 - start2) { return false; } while(start1 <= end1 && start2 <= end2){ if(str1[start1] != str2[start2]){ return false; } start1++; start2++; } return true; } public static void main(String args[]){ RabinKarpSearch rks = new RabinKarpSearch(); System.out.println(rks.patternSearch("TusharRoy".toCharArray(), "sharRoy".toCharArray())); System.out.println(rks.patternSearch("TusharRoy".toCharArray(), "Roy".toCharArray())); System.out.println(rks.patternSearch("TusharRoy".toCharArray(), "shas".toCharArray())); System.out.println(rks.patternSearch("TusharRoy".toCharArray(), "usha".toCharArray())); System.out.println(rks.patternSearch("TusharRoy".toCharArray(), "Tus".toCharArray())); } }