I_R_W14_M35_Java Programowanie dynamiczne - znajdowanie spójnego podciągu
Zadanie 2. Najdłuższy spójny podciąg palindromiczny
Spójny podciąg to taki, którego każde dwa sąsiednie wyrazy były sąsiednimi wyrazami pierwotnego ciągu. Natomiast spójny podciąg palindromiczny to taki podciąg, który czytany w obu kierunkach (czyli od lewej do prawej, jak i wspak) jest identyczny.
W pliku napisy.txt znajduje się 100 ciągów znaków oddzielonych znakiem nowej linii.
Przykładowe dane:
ySSyQTffTQcEWWEc
ZBdUUdBZzPPz
VbbV
Napisz program znajdujący najdłuższy spójny podciąg palindromiczny danego ciągu znaków. Wykorzystaj programowanie dynamiczne.
Specyfikacja problemu:
Dane:
n– długość wejściowego ciągu znaków; liczba naturalnaS[]– ciąg znaków, w którym należy znaleźć najdłuższy podciąg palindromiczny
Wynik:
najdluzszy_palindrom– znaleziony najdłuższy podciąg palindromiczny; ciąg znaków
Użyj napisanego programu do znalezienia najdłuższych podciągów palindormicznych dla każdego z ciągów znaków w pliku napisy.txt. Wyniki zapisz do pliku palindromy.txt, każdy w osobnej linii.
1.
Jedno z bezpośrednich rozwiązań polegałoby na sprawdzeniu każdego spójnego podciągu. Niech n będzie długością wejściowego ciągu znaków. Wszystkich takich spójnych podciągów jest wtedy O(nIndeks górny 2 Indeks górny koniec2). Sprawdzenie czy ciąg długości n jest palindromiczny zajmuje O(n) czasu. Tak określony prosty algorytm siłowy działa w czasie O(nIndeks górny 3 Indeks górny koniec3) . Szybsze rozwiązanie działające w czasie O(nIndeks górny 2 Indeks górny koniec2) może opierać się na programowaniu dynamicznym
2.
Niech d będzie tablicą dwuwymiarową rozmiaru n x n. Wyraz d[i][j] jest równy 1, jeśli spójny podciąg pomiędzy indeksami i oraz j jest palindromiczny.
Np. dla wyrazu „1abdedba254” podciąg „bdedb” jest palindromiczny, zatem wyraz d[2][6]musi być równy 1. Tak samo d[3][5] („ded”) i d[1][7] („abdedba”) też będą równe 1. Z drugiej strony podciąg „1abdedb” nie jest palindromiczny, więc podciąg d[0][6] jest równy 0.
3.
Zapisanie pseudokodu rozpoczniemy od zdefiniowania nagłówka funkcji będącej implementacją algorytmu. Jako argument wymagany jest tylko ciąg znaków S i długość ciągu n.
4.
Następnie zdefiniujemy dwuwymiarową tablicę d o rozmiarze n x n, którą wypełniamy 0. Będziemy wypełniać wyłącznie jej część ponad przekątną. Łatwo zauważyć, że d[i][j] będzie zawsze równe d[j][i], więc nie ma potrzeby wypełniać całej tablicy. Dodatkowo określimy zmienną maks_dlugosc przechowującą dotychczas największą długość palindromicznego spójnego podciągu.
5.
Na początku wypełniamy przekątną tablicy d[]. Pojedynczy znak jest zawsze palindromem, dlatego wszystkie pola d[i][i] dla 0 < = i < n powinny mieć wartość 1.
6.
Następnie zdefiniujemy zmienną pomocniczą start, która będzie przechowywać indeks, od którego rozpoczyna się najdłuższy znaleziony podciąg palindromiczny. W pojedynczej pętli, iterując po ciągu S, będziemy poszukiwać palindromów długości 2.Znajdując taki palindrom pomiędzy S[i]oraz S[i + 1] zapiszemy w d[i][i+1] wartość 1.
7.
Kolejnym krokiem jest utworzenie dwóch zagnieżdżonych pętli, które pozwolą nam wypełnić pozostałe pola w tablicy d[]. Zmienna i będzie wskazywała na początek sprawdzonego podciągu, zmienna k będzie określała jego długość natomiast zmienna j będzie zmienną pomocniczą, której przypiszemy końcowy indeks sprawdzanego podciągu.
8.
W każdej iteracji pętli będziemy chcieli sprawdzić, czy podciąg pomiędzy indeksem i oraz j jest palindromem. Aby tak było, muszą być spełnione dwa warunki: podciąg pomiędzy i + 1 oraz j - 1 musi być palindromem oraz S[i]==S[j]. Jeżeli został znaleziony nowy palindrom musimy również sprawdzić, czy nie jest on nowym najdłuższym znalezionym rozwiązaniem. W takim wypadku ustawiamy zmienną start na indeks i natomiast maks_dlugosc na k.
9.
Na koniec definiujemy tablicę najdluzszy_palindrom[] o długości maks_dlugosc, która pozwoli nam zwrócić znalezione rozwiązanie. Zapiszemy do niej w pętli podciąg zaczynający się na indeksie start, a kończący na start + maks, a następnie zwrócimy._dlugosc‑1
Odpowiedź do zadania
Odpowiedź dla danych z pliku napisy.txt znajduje się w załączniku: