Пређи на садржај

Лексикографски минимална ротација ниске

С Википедије, слободне енциклопедије

У рачунарству, лексикографски минимална ротација ниске, то јест лексикографски најмања кружна подниска представља проблем проналажења такве ротације дате ниске да је та ротација лексикографски најмања међу свим ротацијама те ниске. На пример, лексикографски минимална ротација ниске „ббааццаадд“ би била „ааццааддбб“. Могуће је да одређена ниска има више ротација које су лексикографски минималне, међутим за већину примена то није битно зато што те ротације морају бити међусобно еквивалентне. Проналазак лексикографски минималне ротације ниске има примену за нормализацију ниски. Ако ниске које се посматрају представљају изоморфне структуре као што су на пример графови, ова врста нормализације ниски омогућава једноставну проверу једнакости.[1] Да би се избегло коришћене модуларне аритметике при рачунању индекса у нисци, често се користи трик да се ниска надовеже на саму себе.

Алгоритми[уреди | уреди извор]

Наивни алгоритам[уреди | уреди извор]

Код наивног алгоритма итерира се кроз све узастопне ротације ниске, при чему се памти и ажурира лексикографски најмања ротација на коју се до сада наишло. За ниску дужине н, временска сложеност овог алгоритма у најгорем случају износи O(n2).

Бутов алгоритам[уреди | уреди извор]

Ефикасан алгоритам који решава овај проблем је изнео Бут (1980).[2] Алгоритам користи модификовану функцију за претпроцесирање ниске из КМП алгоритма. Функција неуспеха се за ниску рачуна на уобичајен начин, међутим ниска се ротира током израчунавања па се за неке индексе ниске рачунања врше више одједном. Када су сви индекси функције неуспеха успешно израчунати и када нема потребе за поновном ротацијом ниске, познат је индекс где почиње лексикографски најмања ротација ниске и тај индекс се једноставно враћа. Коректност алгоритма није сасвим лако разумети, али се сам алгоритам једноставно имплементира.

def LCS(S):
    n = len(S)
    S += S      # Nadovezivanje niski da bi se izbegla modularna aritmetika
    f = [-1 for c in S]     # Funkcija neuspeha
    k = 0       # Indeks početka leksikografski najmanje rotacije pronađene do sada
    for j in range(1, 2*n):
        i = f[j-k-1]
        while i != -1 and S[j] != S[k+i+1]:
            if S[j] < S[k+i+1]:
                k = j-i-1
            i = f[i]
        if i == -1 and S[j] != S[k+i+1]:
            if S[j] < S[k+i+1]:
                k = j
            f[j-k] = -1
        else:
            f[j-k] = i+1
    return k

Занимљиво је да се уклањањем свих линија кода које модификују вредност променљиве k добија оригинална претпроцесирајућа функција која се користи у Кнут-Морис-Прат алгоритму, зато што ће променљива k (која представља ротацију) остати нула. Временска сложеност Бутовог алгоритма је O(n), при чему је n дужина ниске. Алгоритам ће извршити највише 3n поређења у најгорем случају, и користи O(n) додатног меморијског простора за чување табеле функције неуспеха.

Шајлоков алгоритам брзе канонизације[уреди | уреди извор]

Шајлок (1981)[3] је предложио алгоритам који има боље перформансе од Бутовог алгоритма. Он је приметио да ако постоји q лексикографски минималних еквивалентних ротација ниске дужине n, тада се оригинална ниска мора састојати од q једнаких подниски дужине d=n/q. Предложени алгоритам користи само n + d/2 поређења и константно додатне меморије.

Алгоритам има две фазе. Прва фаза служи за проналажење и одбацивање индекса ниске који засигурно нису места где лексикографски минимална ротација ниске почиње. Друга фаза представља проналажење индекса почетка лексикографски минималне ротације ниске међу преосталим индексима.

Дувалов алгоритам Линдон факторизације[уреди | уреди извор]

Дувал (1983)[4] је такође предложио ефикасан алгоритам који се базира на факторизацији ниске у своје компоненте Линдонове речи, и извршава се у линеарном времену и користи константно додатне меморије.

Варијанте[уреди | уреди извор]

Шајлок (1979)[5] је преложио ефикасан алгоритам за поређење две кружне ниске на једнакост без потребе за њиховом нормализацијом. Овај алгоритам је нашао примену у брзом генерисању одређених хемијских структура без њиховог понављања.

Види још[уреди | уреди извор]

Литература[уреди | уреди извор]

  1. ^ Келлогг С. Боотх; Цолбоурн, Цхарлес Ј. (1980). „Линеар Тиме Аутоморпхисм Алгоритхмс фор Треес, Интервал Грапхс, анд Планар Грапхс”. СИАМ Јоурнал он Цомпутинг. Социетy фор Индустриал анд Апплиед Матхематицс. 10 (1): 203—225. ИССН 0097-5397. дои:10.1137/0210015. 
  2. ^ Келлогг С. Боотх (1980). „Леxицограпхицаллy леаст цирцулар субстрингс”. Информатион Процессинг Леттерс. Елсевиер. 10 (4-5): 240—242. ИССН 0020-0190. дои:10.1016/0020-0190(80)90149-0. 
  3. ^ Yосси Схилоацх (1981). „Фаст цанонизатион оф цирцулар стрингс”. Јоурнал оф Алгоритхмс. Елсевиер. 2 (2): 107—121. ИССН 0196-6774. дои:10.1016/0196-6774(81)90013-4. 
  4. ^ Јеан Пиерре Дувал (1983). „Фацторизинг wордс овер ан ордеред алпхабет”. Јоурнал оф Алгоритхмс. Елсевиер. 8 (8): 363—381. ИССН 0196-6774. дои:10.1016/0196-6774(83)90017-2. 
  5. ^ Yосси Схилоацх (1979). „А фаст еqуиваленце-цхецкинг алгоритхм фор цирцулар листс”. Информатион Процессинг Леттерс. Елсевиер. 8 (5): 236—238. ИССН 0020-0190. дои:10.1016/0020-0190(79)90114-5.