2013-09-04 2 views
5

Учитывая следующую задачу:Найдите наименьший период ввода строки в O (n)?

Определение:

Пусть S будет строкой в ​​алфавите Е. S' это наименьший период S , если S' является самым маленьким, так что строка:

S = (S')^k (S''),

, где S'' является префиксом S. Если такой S' не существует, то S является не периодическим.

Пример: S = abcabcabcabca. Затем abcabc является периодом с S = abcabc abcabc a, но наименьший период составляет abc с S = abc abc abc abc a.

Дайте алгоритму, чтобы найти наименьший период ввода строки S или , заявить, что S не является периодическим.

Подсказка: Вы можете сделать это в O(n) ...

Мое решение: Мы используем KMP, который работает в O (N).

По определению проблемы S = (S ')^k (S' '), то я думаю, что если мы создадим автоматы за самый короткий период и найдем способ найти этот самый короткий период, то я закончен.

Проблема заключается в том, где поставить FAIL стрелка автоматов ...

Любые идеи, было бы весьма признателен,

С уважением

+0

Не было бы 'S = (S '') (S ')^k', если' S''' является префиксом, или это обозначение, добавленное к фронту? – Mikeb

+1

@Mikeb: Нет, посмотрите на пример: здесь 'S = abcabcabcabca',' S '= abc' и 'S' '= a' ..., так как' S''' является последним символом. – ron

+0

, так что если 'S = qweabcabcabc', строка не является периодической? Угадайте, что у меня просто языковой каламбур, в вашем примере я бы назвал 'S''' суффикс. – Mikeb

ответ

0

Я не уверен, что я понимаю вашу попытку решения , KMP - полезная подпрограмма, хотя - наименьший период - это то, как KMP перемещает игольную строку (т. Е. S) после полного совпадения.

0

эта проблема может быть решена с использованием функции Z, this учебник может вам помочь.

0

Посмотрите, подходит ли это решение для O (n). Я использовал поворот строк.

public static int stringPeriod(String s){ 

    String s1= s; 
    String s2= s1; 

    for (int i=1; i <s1.length();i++){ 
     s2=rotate(s2); 
     if(s1.equals(s2)){ 
      return i; 
     } 
    } 

    return -1; 
} 

public static String rotate(String s1){ 

    String rotS= s1; 

    rotS = s1.substring(1)+s1.substring(0,1); 

    return rotS; 

} 

Полная программа доступна в this github repository

+1

Это явно «O (n²)» – fjardon

+0

@fjardon Подстрока O (n). Это верно ! Это было O (1) в более старых версиях Java. –

+0

Nehal: string.equals - O (n). (Предположим, что строка состоит из 'n-1' As, за которой следует B. Тогда вам нужно выполнить сравнения символов O (n²) в целом.) Но это не проблема: проблема в том, что алгоритм работает только в том случае, если строка чисто периодический (S '' пуст в терминах определения периодического.) – rici