Created
December 30, 2016 22:30
-
-
Save vinnyoodles/c643c6f9d3c36771935459c8534da20b to your computer and use it in GitHub Desktop.
Knuth Morris Pratt string searching algorithm in Java
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
import java.util.Scanner; | |
public class KMP { | |
public static void main(String[] args) { | |
Scanner kb = new Scanner(System.in); | |
String search = kb.next(); | |
String target = kb.next(); | |
int result = KMP(search, target); | |
if (result == -1) { | |
System.out.println("NO"); | |
} | |
else { | |
System.out.println("YES"); | |
} | |
} | |
public static int KMP(String search, String target) { | |
int[] failureTable = failureTable(target); | |
int targetPointer = 0; // current char in target string | |
int searchPointer = 0; // current char in search string | |
while (searchPointer < search.length()) { // while there is more to search with, keep searching | |
if (search.charAt(searchPointer) == target.charAt(targetPointer)) { // case 1 | |
// found current char in targetPointer in search string | |
targetPointer++; | |
if (targetPointer == target.length()) { // found all characters | |
int x = target.length() + 1; | |
return searchPointer - x; // return starting index of found target inside searched string | |
} | |
searchPointer++; // move forward if not found target string | |
} else if (targetPointer > 0) { // case 2 | |
// use failureTable to use pointer pointed at nearest location of usable string prefix | |
targetPointer = failureTable[targetPointer]; | |
} else { // case 3 | |
// targetPointer is pointing at state 0, so restart search with current searchPointer index | |
searchPointer++; | |
} | |
} | |
return -1; | |
} | |
/** | |
* Returns an int[] that points to last valid string prefix, given target string | |
*/ | |
public static int[] failureTable(String target) { | |
int[] table = new int[target.length() + 1]; | |
// state 0 and 1 are guarenteed be the prior | |
table[0] = -1; | |
table[1] = 0; | |
// the pointers pointing at last failure and current satte | |
int left = 0; | |
int right = 2; | |
while (right < table.length) { // RIGHT NEVER MOVES RIGHT UNTIL ASSIGNED A VALID POINTER | |
if (target.charAt(right - 1) == target.charAt(left)) { // when both chars before left and right are equal, link both and move both forward | |
left++; | |
table[right] = left; | |
right++; | |
} else if (left > 0) { // if left isn't at the very beginning, then send left backward | |
// by following the already set pointer to where it is pointing to | |
left = table[left]; | |
} else { // left has fallen all the way back to the beginning | |
table[right] = left; | |
right++; | |
} | |
} | |
return table; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
search = "sadbutsad" target="sad" should give 0 but answer -2