Manacher-algoritmus
Kiejtés
- IPA: [ ˈmɒnɒɦɛrɒlɡoritmuʃ]
Főnév
Manacher-algoritmus
A Manacher-algoritmus egy hatékony módszer arra, hogy egy adott szövegben minden pozícióra meghatározza a leghosszabb palindrómát, amely azon a pozíción keresztül halad. Az algoritmus időbonyolultsága (O(n)), ahol (n) a szöveg hossza. Ez jelentősen gyorsabb, mint egy naiv (O(n^2))-es megközelítés.
Alapelvek
- Palindrómák jellemzői:
- Egy palindróma olyan szövegrész, amely elölről és hátulról olvasva is ugyanaz (pl. “radar”, “level”).
- Középpont-alapú iteráció:
- Minden pozícióra kiszámítja a leghosszabb palindrómát, amely azon keresztül halad.
- Tükrözés és jobb határ használata:
- Az algoritmus a már kiszámított eredményeket újrapéldányosítja, hogy gyorsítsa a számításokat.
Működés
- Előkészítés:
- A bemenetet kiegészíti speciális karakterekkel (pl. ‘#’ vagy ‘^’), hogy az egyenletes hosszúságú palindrómákat is kezelni lehessen (pl. “abba” -> “#a#b#b#a#”).
- Tükörszimmetria kihasználása:
- Ha egy palindróma egy másik palindróma részhalmaza, akkor az új palindrómát részben tükrözéssel határozza meg.
- Megjegyzett határok:
- Egy “jobb határ” ((R)) és egy “középpont” ((C)) segíti a számításokat:
- (R): Az aktuálisan ismert legnagyobb hatótávolságú palindróma vége.
- (C): Az ehhez tartozó középpont.
- Egy “jobb határ” ((R)) és egy “középpont” ((C)) segíti a számításokat:
- Palindrómák kiszámítása:
- Minden pozícióra kiszámítja a palindróma hosszát, és a (R), (C) értékeket szükség szerint frissíti.
Pszeudokód
function Manacher(s): T = átalakított_bemenet(s) # Pl. "#a#b#b#a#" n = T hossza P = [0] * n # Palindróma sugarak C = 0 # Aktuális középpont R = 0 # Jobb határ minden i 0-tól n-1-ig: tükrözött = 2 * C - i # Tükrözött pozíció C-hez képest ha i < R: P[i] = min(R - i, P[tükrözött]) # Tükrözött érték felhasználása # Próbáld bővíteni a palindrómát amíg T[i + P[i] + 1] == T[i - P[i] - 1]: P[i] += 1 # Frissítsd C-t és R-t, ha szükséges ha i + P[i] > R: C = i R = i + P[i] térj vissza P
Python implementáció
def manacher(s):
# Átalakított szöveg (# karakterekkel)
t = "#" + "#".join(s) + "#"
n = len(t)
p = [0] * n # Palindrómák sugarai
C, R = 0, 0 # Középpont és jobb határ
for i in range(n):
mirr = 2 * C - i # Tükrözött pozíció
if i < R:
p[i] = min(R - i, p[mirr])
# Palindróma bővítése
while i + p[i] + 1 < n and i - p[i] - 1 >= 0 and t[i + p[i] + 1] == t[i - p[i] - 1]:
p[i] += 1
# Frissítsd a középpontot és a jobb határt
if i + p[i] > R:
C, R = i, i + p[i]
# Eredeti palindrómák kinyerése
max_length = max(p)
center_index = p.index(max_length)
start = (center_index - max_length) // 2
return s[start:start + max_length], max_length
# Példa használat
s = "babad"
longest_palindrome, length = manacher(s)
print(f"Leghosszabb palindróma: {longest_palindrome}, Hossza: {length}")
Kimenet:
Leghosszabb palindróma: bab, Hossza: 3
C++ implementáció
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
pair<string, int> manacher(const string& s) {
// Átalakított szöveg
string t = "#";
for (char c : s) {
t += c;
t += "#";
}
int n = t.size();
vector<int> p(n, 0); // Palindrómák sugarai
int C = 0, R = 0; // Középpont és jobb határ
for (int i = 0; i < n; i++) {
int mirr = 2 * C - i; // Tükrözött pozíció
if (i < R) {
p[i] = min(R - i, p[mirr]);
}
// Palindróma bővítése
while (i + p[i] + 1 < n && i - p[i] - 1 >= 0 && t[i + p[i] + 1] == t[i - p[i] - 1]) {
p[i]++;
}
// Frissítsd a középpontot és a jobb határt
if (i + p[i] > R) {
C = i;
R = i + p[i];
}
}
// Eredeti palindrómák kinyerése
int max_length = *max_element(p.begin(), p.end());
int center_index = max_element(p.begin(), p.end()) - p.begin();
int start = (center_index - max_length) / 2;
return {s.substr(start, max_length), max_length};
}
int main() {
string s = "babad";
auto result = manacher(s);
cout << "Leghosszabb palindróma: " << result.first << ", Hossza: " << result.second << endl;
return 0;
}
Kimenet:
Leghosszabb palindróma: bab, Hossza: 3
Összegzés
A Manacher-algoritmus gyors és hatékony megoldást nyújt a leghosszabb palindrómák keresésére: - Időbonyolultság: (O(n)), köszönhetően a tükrözés és jobb határ használatának. - Előny: Minden palindrómát megtalál egyetlen futtatás alatt, függetlenül a bemeneti szöveg hosszától. - Alkalmazás: Szövegelemzés, bioinformatika, karakterlánc-problémák optimalizálása.
Fordítások
Tartalom
- Manacher-algoritmus - Értelmező szótár (MEK)
- Manacher-algoritmus - Etimológiai szótár (UMIL)
- Manacher-algoritmus - Szótár.net (hu-hu)
- Manacher-algoritmus - DeepL (hu-de)
- Manacher-algoritmus - Яндекс (hu-ru)
- Manacher-algoritmus - Google (hu-en)
- Manacher-algoritmus - Helyesírási szótár (MTA)
- Manacher-algoritmus - Wikidata
- Manacher-algoritmus - Wikipédia (magyar)