assume you have a text - int[] text = {10, 20, 30, 25}
the suffix array will be:
suffix[0] = {10, 20, 30, 25}
suffix[1] = {20, 30, 25}
suffix[2] = {30, 25}
suffix[3] = {25}
if we sort them in lexical order, we get this suffix[0] < suffix[1] < suffix[3] < suffix[2]
Provide a method to get the sorted suffix index array. Follow up: if I want to search whether int[] sub = {20,30} is in the text, how to do it, suppose we already have the sorted suffix index array, do it in O(NlogN).
public static class Suffix {
public int[] suffixArray;
public int index;
}
public int[] constructSortedSuffixIndexArray(List<int[]> suffixArray) {
Suffix[] array = new Suffix[suffixArray.size()];
for (int i=0; i<array.length; i++) {
Suffix s = new Suffix();
s.index = i;
s.suffixArray = suffixArray.get(i);
array[i] = s;
}
int[] results = new int[suffixArray.size()];
Comparator<Suffix> comp = new Comparator<Suffix>(){
@Override
public int compare(Suffix s1, Suffix s2) {
int[] a1 = s1.suffixArray;
int[] a2 = s2.suffixArray;
int i=0;
int j=0;
while(i<a1.length&&j<a2.length) {
if (a1[i]<a2[j]) {
return -1;
} else if (a1[i]>a2[j]) {
return 1;
}
i++;
j++;
}
if (i==a1.length&&j==a2.length) {
return 0;
}
if (i==a1.length) {
return -1;
}
if (j==a2.length) {
return 1;
}
return 0;
}
};
Arrays.sort(array, comp);
for (int i=0; i<results.length; i++) {
results[i] = array[i].index;
}
return results;
}
//search particular pattern
public boolean searchPattern(int[] pattern, List<int[]> suffixArray, int[] suffixOrderArray) {
int left = 0;
int right = suffixOrderArray.length-1;
while (left<right) {
int middle = left + (right-left)/2;
int order = suffixOrderArray[middle];
int comp = compareArray(pattern, suffixArray.get(order));
if (comp==0) {
return true;
} else if (comp<0) {
right = middle-1;
} else {
left = middle+1;
}
}
return false;
}
public int compareArray(int[] sub, int[] suffix) {
int i=0;
int j=0;
while(i<sub.length&&j<suffix.length) {
if (sub[i]>suffix[j]) {
return 1;
} else if (sub[i]<suffix[j]){
return -1;
}
i++;
j++;
}
if (i==sub.length&&j==sub.length) {
return 0;
}
return (i==sub.length) ? 0 : 1;
}