Знаходження найбільш тривалої послідовності, що повторюється


9

З огляду на рядок , я хотів би знайти найдовший підряд (щонайменше двічі) підряд. Тобто, я хотів би знайти рядок який є подальшим (не повинно бути суміжним) з таким, що . Тобто, - рядок, половинки якої з’являються двічі поспіль. Зауважимо, що - це підряд , але не обов'язково підрядка.swsw=wwwws

Приклади:

Для 'ababccabdc' це буде 'abcabc', тому що 'abc' = 'abc' і 'abc' з’являється (принаймні) двічі в 'ababccabdc'.

Для 'addbacddabcd' одним із варіантів є 'dddd', тому що 'dd' з’являється двічі (я не можу використовувати одну і ту ж букву кілька разів, але тут у мене 4 'd, так це нормально), але її довжина 4. Я можу знайти кращу довжини 8: 'abcdabcd', оскільки 'abcd' є підрядком 'addbacddabcd', що з’являється двічі.

Мені цікаво знайти найдовшу послідовність, що повторюється. Це також називається "пошук найдовшого / найбільшого квадрата", але я прочитав багато статей, у яких квадрат визначений для підрядка, а не для підпорядкування.

Я легко можу використовувати алгоритм грубої сили, який буде приймати шляхом повторення всіх варіантів точки розриву в рядку, і тоді у мене будуть два рядки, в яких я буду шукати найбільшу / найдовшу спільну послідовність, але кожна перевірка буде приймати використанням динамічної методики програмування, тому весь час буде . Я знайшов більш ефективний алгоритм для найдовшого загального підпорядкування, який займає , тому час роботи буде .O(n3)O(n2)O(n3)O(n2logn)O(n3logn)

Я шукаю більш ефективний алгоритм для найбільш тривалої повторюваної задачі про підряд. Можливо, моя думка про повторення над усіма точками пробивання занадто багато часу, і її можна звести до меншої кількості ітерацій. Або, можливо, алгоритм з іншим ставленням може вирішити цю проблему.

Я шукав у багатьох журналах та попередніх питаннях, і більшість знайдених нами результатів стосувались підрядок, а не про послідовності.

Я також читав, що це можна зробити за допомогою дерев суфіксів, але це теж стосувалося підрядків, і я не впевнений, чи можна продовжити таку ідею для подальшої подачі.

Я шукаю рішення, яке працює в часі . Якщо існує один раз це буде ще краще (я не впевнений, чи існує такий).O(n2)O(nlogn)


4
Знайдіть дерева суфіксів чи масиви суфіксів.
Псевдонім

1
Це дуже малоймовірно, що o(n2)- для цієї проблеми існує алгоритм часу, оскільки, якби він був, ви можете використовувати його для перемоги за найвідомішим алгоритмом пошуку LCS двох довжин.n струни u і v наступним чином: Сформуйте рядок xuxv, де x є n+1копії символу $, який не відображається ні в одномуu або v, а потім запустіть свій o(n2)-час алгоритм на ньому. Обидві "половинки" найдовшої повторюваної послідовності обов'язково почнуться зx, тому одна половина походить від кожного з u і v, розв’язання задачі LCS.
j_random_hacker

@j_random_hacker LCS можна вирішити в O(n+m) за допомогою дерева суфіксів або в O(nlogn)за допомогою прокатки хешей.
Зло

@Evil: Я ще не розумію, як, ви могли б дати трохи детальніше? (Ви впевнені, що не думаєте про найдовший рядок Sub , який можна вирішити за тих часових складностей?)
j_random_hacker

@j_random_hacker Я подумав, що ти порівнюєш цілеспрямовано o(n2)з LCS (послідовно), але тут, як ви вже згадували, так, я навіть не бачив робочого рішення в n ^ 2 для найдовшого загального наслідку (я знайшов один динамічний код програмування, розповсюджений на багатьох сторінках, який є недоліком, подібним до відповіді нахилу). Так просто я неправильно зрозумів ваш коментар, вибачте.
Зло

Відповіді:


-1

Ось динамічне рішення програмування.

Припустимо, що вхідний рядок є x1xn. Створіть таблицюT рядки та стовпці яких індексуються 0,,n (де n довжина рядка), заповнене правилом

T[i,j]={0if i=0 or j=0,T[i1,j1]+1if xi=xj and ij,max(T[i1,j],T[i,j1])otherwise.
Відповідь така T[n,n].

Припустимо, ми є у деяких i,j з i=j+1, і умова у вашій ifзаяві вірна. Тоді dp[i][j] = dp[i - 1][j - 1] + 1мається на увазі, що персонаж в положенніi1=jє частиною обох підрядів.
j_random_hacker

3
Ласкаво просимо до інформатики! Будь ласка, позбудьтеся вихідного коду та замініть його ідеями, псевдокодами та аргументами правильності. Дивіться тут і тут для відповідних мета-дискусій.
Рафаель

@Raphael Рекурсивна формула не вважається вихідним кодом.
Число945

1
@BreakingBenjamin Залежно від вашої мови вибору, ви можете записати заданий повтор більш-менш буквально. Справа в тому, що пояснення тут немає.
Рафаель
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.