Pronađite podnizice koji su palindromi u Javi
1. Pregled
U ovom ćemo brzom vodiču proći kroz različite pristupe pronalaženje svih podnizova unutar datog niza koji su palindromi. Također ćemo primijetiti vremensku složenost svakog pristupa.
2. Pristup grube sile
U ovom ćemo pristupu jednostavno prelaziti kroz ulazni niz da bismo pronašli sve podnizove. Istodobno ćemo provjeriti je li podniz palindrom ili nije:
javni Postavi findAllPalindromesUsingBruteForceApproach (String input) {Set palindromes = new HashSet (); for (int i = 0; i <input.length (); i ++) {for (int j = i + 1; j <= input.length (); j ++) {if (isPalindrome (input.substring (i, j ))) {palindromes.add (input.substring (i, j)); }}} povratni palindromi; }
U gornjem primjeru samo uspoređujemo podniz sa njegovim reverzom kako bismo vidjeli je li palindrom:
privatni logički isPalindrome (unos niza) {StringBuilder plain = novi StringBuilder (ulaz); StringBuilder reverse = plain.reverse (); return (reverse.toString ()). jednako (ulaz); }
Naravno, lako možemo birati između nekoliko drugih pristupa.
Složenost vremena ovog pristupa je O (n ^ 3). Iako je to možda prihvatljivo za male ulazne nizove, trebat će nam učinkovitiji pristup ako provjeravamo palindrome u velikim količinama teksta.
3. Pristup centralizacije
Ideja u pristupu centralizacije je da smatrajte svaki lik stožićem i proširite se u oba smjera kako biste pronašli palindrome.
Proširit ćemo se samo ako se znakovi na lijevoj i desnoj strani podudaraju, kvalificirajući niz kao palindrom. Inače nastavljamo sa sljedećim likom.
Pogledajmo brzu demonstraciju u kojoj ćemo svaki lik smatrati središtem palindroma:
javni Postavi findAllPalindromesUsingCenter (unos niza) {Postavi palindrome = novi HashSet (); for (int i = 0; i <input.length (); i ++) {palindromes.addAll (findPalindromes (input, i, i + 1)); palindromi.addAll (findPalindromes (input, i, i)); } povratni palindromi; }
Unutar gornje petlje širimo se u oba smjera kako bismo dobili skup svih palindroma usredotočenih na svakom položaju. Pozivanjem metode pronaći ćemo palindrome i parne i neparne duljine naćiPalindrome dvaput u petlji:
private Set findPalindromes (String input, int low, int high) {Postavi rezultat = novi HashSet (); while (low> = 0 && high <input.length () && input.charAt (low) == input.charAt (high)) {result.add (input.substring (low, high + 1)); nisko--; visoka ++; } vratiti rezultat; }
Složenost vremena ovog pristupa je O (n ^ 2). Ovo je poboljšanje u odnosu na naš grubi pristup, ali možemo i bolje, kao što ćemo vidjeti u sljedećem odjeljku.
4. Manacherov algoritam
Manacherov algoritampronalazi najdužu palindromsku podniz u linearnom vremenu. Ovim ćemo algoritmom pronaći sve podnizove koji su palindromi.
Prije nego što uđemo u algoritam, inicijalizirat ćemo nekoliko varijabli.
Prvo ćemo zaštititi ulazni niz s graničnim znakom na početku i na kraju prije pretvaranja rezultirajućeg niza u niz znakova:
String formattedInput = "@" + input + "#"; char inputCharArr [] = formattedInput.toCharArray ();
Zatim ćemo upotrijebiti dvodimenzionalni niz radius s dva reda - jedan za pohranu duljina palindroma neparne duljine, a drugi za pohranu duljina palindroma parne duljine:
int radijus [] [] = novi int [2] [input.length () + 1];
Dalje, prelazit ćemo kroz ulazni niz da bismo pronašli duljinu palindroma usredotočenog na položaju ja i pohranite ovu duljinu u radius[][]:
Postavi palindrome = novi HashSet (); int max; za (int j = 0; j <= 1; j ++) {radijus [j] [0] = max = 0; int i = 1; while (i <= input.length ()) {palindromes.add (Character.toString (inputCharArr [i])); while (inputCharArr [i - max - 1] == inputCharArr [i + j + max]) max ++; polumjer [j] [i] = max; int k = 1; while ((radijus [j] [i - k]! = max - k) && (k <max)) {radijus [j] [i + k] = Math.min (radijus [j] [i - k], max - k); k ++; } max = Math.max (max - k, 0); i + = k; }}
Konačno, preći ćemo niz radius[][] za izračunavanje palindromskih podnizova usredotočenih na svakom položaju:
for (int i = 1; i <= input.length (); i ++) {for (int j = 0; j 0; max--) {palindromes.add (input.substring (i - max - 1, max + j + i - 1)); }}}
Vremenska složenost ovog pristupa je O (n).
5. Zaključak
U ovom kratkom članku razgovarali smo o vremenskoj složenosti različitih pristupa pronalaženju podnizova koji su palindromi.
Kao i uvijek, puni izvorni kod primjera dostupan je na GitHub-u.