Вычислить прогоны строки


11

Рассмотрим следующие определения, взятые из «Количество прогонов в строке » У. Риттера. Обратите внимание, что слово, строка и подстрока являются примерно синонимами.

Прогон в строке - это нерасширяемый (с тем же минимальным периодом) периодический сегмент в строке.

Период p слова w - это любое положительное целое число p, такое что w [i] = w [i + p] всякий раз, когда определены обе стороны этого уравнения. Пусть per (w) обозначает размер наименьшего периода w. Мы говорим, что слово w периодично тогда и только тогда, когда per (w) <= | w | / 2.

Для примера рассмотрим строку x = abcab. per(abcab) = 3как x[1] = x[1+3] = a, x[2]=x[2+3] = bи нет меньшего периода. Поэтому строка не abcabявляется периодической. Однако строка ababявляется периодической согласно (abab) = 2.

Прогон (или максимальная периодичность) в строке w - это интервал [i ... j] с j> = i, такой что

  • w [i ... j] - периодическое слово с периодом p = per (w [i ... j])
  • Это максимально. Формально, ни w [i-1] = w [i-1 + p], ни w [j + 1] = w [j + 1-p]. Неофициально прогон не может содержаться в большем прогоне с тем же периодом.

Обозначим через RUNS (w) множество прогонов w.

Примеры

Четыре серии atattatt: [4,5] = tt, [7,8] = tt, [1,4] = atat, [2,8] = tattatt.

Строка aabaabaaaacaacacсодержит следующие 7 прогонов:

[1,2] = aa, [4,5] = aa, [7,10] = aaaa, [12,13] = aa, [13,16] = acac, [1,8] = aabaabaa, [9 , 15] = аакаака.

Ваш вывод должен быть список прогонов. Каждый прогон должен указывать интервал, который он представляет, но не должен выводить саму подстроку. Точное форматирование может быть любым удобным для вас.

В примерах используется 1-индексация, но вы можете использовать 0-индексацию, если это более удобно.

ЗАДАЧА

Напишите код, который содержит строку w, выведите RUNS (w).

Языки и ввод

Вы можете использовать любой язык, который вам нравится, и принимать строку ввода в любой удобной для вас форме. Тем не менее, вы должны предоставить полную программу, и вы должны показать пример вашего кода, запущенного на примере ввода.


4
Хорошая задача, но есть ли хорошая причина для отмены функций по умолчанию и запрета функций?
Мартин Эндер

@MartinEnder Это просто мои предпочтения. Людям проще просто скопировать и вставить код и попробовать его сами, что, в свою очередь, делает ответы более интересными для большего количества людей.

4
Но это также вызывает много накладных расходов, что делает конкуренцию несправедливой для языков с подробным синтаксисом. Например, я бы не играл в гольф на Яве, если бы мне приходилось писать class A{public static ...}каждый раз, когда я хотел написать код для гольфа
Bassdrop Cumberwubwubwub

@BassdropCumberwubwubwub Я вижу, есть плюсы и минусы. Мне случается весить плюсы сильнее. Я думаю, что в любом случае наиболее интересно сравнивать длину ответов для гольфа на похожих языках, а не сравнивать APL с Python, например.

«цикл максимален, если он не полностью содержится в каком-либо большем цикле», но в вашем первом примере [7,8] полностью содержится в [2,8]. Или вы строго говорите о прогонах, которые повторяют одну и ту же подстроку?
Адицу ушел, потому что SE это зло

Ответы:


2

Pyth, 38 байт

{smm,hk+ekdfgaFTdcx1xM.ttB+0qVQ>QdZ2Sl

  m                                 SlQ   map for d in [1, …, len(input)]:
                            qVQ>Qd          pairwise equality of input[:-d] and input[d:]
                        tB+0                duplicate this list, prepending 0 to one copy
                      .t          Z         transpose, padding with 0
                    xM                      pairwise xor
                  x1                        find all occurrences of 1
                 c                 2        chop into groups of 2
           f                                filter for groups T such that:
             aFT                              the absolute difference between its elements
            g   d                             is greater than or equal to d
   m                                        map for groups k:
     hk                                       first element
    ,  +ekd                                   pair with the last element plus d
 s                                        concatenate
}                                         deduplicate

Тестирование


Я получаю "[[3, 5], [6, 8], [0, 4], [1, 8]]" от "atattatt". Представляет ли [3,5] «tt»? Было бы здорово, если бы вы могли объяснить алгоритм, который вы использовали, а также на высоком уровне.

@Lembik Да, [i, j]представляет собой срез начиная между (0-индексированных) символов i-1и iи заканчивая между символами j-1и j. Это стандартное соглашение в Pyth и большинстве вменяемых языков, как и должно быть (см. Здесь и здесь ).
Андерс Касеорг

Отлично. Можно ли описать ваше решение интуитивно? Я не могу реконструировать его из вашего описания кода, к сожалению.

1
@Lembik Предположим, мы ищем прогоны периода d. Мы находим все места, где символ i соответствует символу i + d. Затем мы находим прогоны как минимум d последовательных таких мест. Повторите для всех d. Мы должны дедуплицировать в конце, потому что реальный период мог быть только делителем d.
Андерс Касеорг

1

CJam, 66

q:A,2m*{~A>_@)_@<2*@@2*<=},{_2$-2>2,.+={+}&}*]{[_1=\)\0=2*)+]}%_&p

Попробуйте онлайн

Краткое объяснение:

Алгоритм работает в 4 этапа (первые 3 из них соответствуют 3 основным блокам, которые вы можете наблюдать):

  1. Найдите все пары [index index], которые соответствуют дублированной подстроке (такой как aba aba aaacaacac); это части трасс.
  2. Объедините пары, которые являются частью одного и того же прогона, то есть последовательных индексов и одинаковой длины / периода.
  3. Построить фактические прогоны, взяв минимальный индекс и максимальный индекс + 2 * длина - 1.
  4. В конце удалите дублированные прогоны (те же самые интервалы, полученные с другим периодом)

Я бы больше хотел сыграть в гольф, так что все это может измениться.


Спасибо тебе за это. Не могли бы вы объяснить алгоритм, который вы использовали тоже, пожалуйста?

1
@Lembik хорошо, обновлено
aditsu ушел, потому что SE ЗЛО
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.