strangedb/src/main/java/it/cavallium/strangedb/java/objects/lists/KMP.java

59 lines
2.1 KiB
Java

package it.cavallium.strangedb.java.objects.lists;
public class KMP {
public static int KMP(CharSequence content, CharSequence stringToFind) {
int[] failureTable = failureTable(stringToFind);
int targetPointer = 0; // current char in target string
int searchPointer = 0; // current char in search string
while (searchPointer < content.length()) { // while there is more to search with, keep searching
if (content.charAt(searchPointer) == stringToFind.charAt(targetPointer)) { // case 1
// found current char in targetPointer in search string
targetPointer++;
if (targetPointer == stringToFind.length()) { // found all characters
int x = stringToFind.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(CharSequence 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;
}
}