Полагаю, это зависит от того, как долго вы ищите последовательности.
Я бы использовал Guava Multiset
, перебрал бы последовательность, записал все подпоследовательности в Multiset и отсортировал их по вхождению. Вот пример реализации:
public static String getMostFrequentSequence(final String input, final int patternLength) {
final Multiset<String> multiset = HashMultiset.create();
final int length = patternLength < 0 ? input.length() : Math.min(patternLength, input.length());
for (int l = 2; l < length; l++) {
for (int o = 0; o < input.length() - l; o++) {
multiset.add(input.substring(o, o + l));
}
}
return Ordering.from(new Comparator<Entry<String>>() {
public int compare(final Entry<String> o1, final Entry<String> o2) {
return
ComparisonChain.start()
.compare(o1.getCount(), o2.getCount())
.compare(o1.getElement(), o2.getElement())
.result();
}
}).max(multiset.entrySet()).getElement();
}
А что касается производительности: этот метод тестирования занимает на моей машине около секунды для неограниченной длины и около 25 миллисекунд, когда я ограничиваю длину шаблона до 12 символов
public static void main(final String[] args) throws Exception {
final StringBuilder sb = new StringBuilder();
final Random random = new Random();
for (int i = 0; i < 1000; i++) {
sb.append(random.nextInt(10));
}
final long t1 = System.currentTimeMillis();
final String input = sb.toString();
System.out.println(input);
System.out.println(getMostFrequentSequence(input, -1));
System.out.println(System.currentTimeMillis() - t1);
final long t2 = System.currentTimeMillis();
System.out.println(getMostFrequentSequence(input, 12));
System.out.println(System.currentTimeMillis() - t2);
}