import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; public class SuffixArray { private static final StringBuilder STRING_BUILDER = new StringBuilder(); private static final char DEFAULT_END_SEQ_CHAR = '$'; private final char endSeqChar; private String string; private ArrayList suffixArray; private ArrayList KMRarray; public SuffixArray(CharSequence sequence) { this(sequence, DEFAULT_END_SEQ_CHAR); } public SuffixArray(CharSequence sequence, char endChar) { endSeqChar = endChar; string = buildStringWithEndChar(sequence); } public ArrayList getSuffixArray() { if (suffixArray == null) KMRalgorithm(); return suffixArray; } public ArrayList getKMRarray() { if (KMRarray == null) KMRalgorithm(); return KMRarray; } public String getString(){ return string; } private void KMRalgorithm() { final int length = string.length(); ArrayList KMRinvertedList = new ArrayList(); ArrayList KMR = getBasicKMR(length); int radius = 1; while (radius < length) { KMRinvertedList = getKMRinvertedList(KMR, radius, length); KMR = getKMR(KMRinvertedList, length); radius *= 2; } KMRarray = new ArrayList(KMR.subList(0, length)); suffixArray = new ArrayList(); for (KMRsWithIndex kmr : KMRinvertedList) { suffixArray.add(new Integer(kmr.index)); } } private ArrayList getKMR(ArrayList KMRinvertedList, int length) { final ArrayList KMR = new ArrayList(length*2); for (int i=0; i<2*length; i++) KMR.add(new Integer(-1)); int counter = 0; for (int i=0; i0 && substringsAreEqual(KMRinvertedList, i)) counter++; KMR.set(KMRinvertedList.get(i).index, new Integer(counter)); } return KMR; } private boolean substringsAreEqual(ArrayList KMRinvertedList, int i) { return (KMRinvertedList.get(i-1).beginKMR.equals(KMRinvertedList.get(i).beginKMR) == false) || (KMRinvertedList.get(i-1).endKMR.equals(KMRinvertedList.get(i).endKMR) == false); } private ArrayList getKMRinvertedList(ArrayList KMR, int radius, int length) { final ArrayList KMRinvertedList = new ArrayList(); for (int i=0; i() { @Override public int compare(KMRsWithIndex A, KMRsWithIndex B) { if (A.beginKMR.equals(B.beginKMR) == false) return A.beginKMR.compareTo(B.beginKMR); if (A.endKMR.equals(B.endKMR) == false) return A.endKMR.compareTo(B.endKMR); return A.index.compareTo(B.index); } } ); return KMRinvertedList; } private ArrayList getBasicKMR(int length) { final ArrayList result = new ArrayList(length*2); final char[] characters = string.toCharArray(); for (int i=0; i