Baeza-Yates-Gonnet-algoritmus
Kiejtés
- IPA: [ ˈbɒɛzɒiɒtɛʒɡonːɛtɒlɡoritmuʃ]
Főnév
Baeza-Yates-Gonnet-algoritmus
A Baeza-Yates-Gonnet-algoritmus egy hatékony szövegkereső algoritmus, amelyet gyors substring (részsztring) keresésére fejlesztettek ki nagy szövegekben. Az algoritmus egyesíti a hashing és a szuffixfák előnyeit, hogy gyors szövegegyezést érjen el.
Az algoritmus leginkább a hash-alapú szövegkeresési módszerek csoportjába tartozik, és a Rabin-Karp-eljáráshoz hasonlóan működik, de optimalizálva van az illesztési műveletek csökkentésére.
Működési elv
- Hashing:
- Az algoritmus a keresett minta (pattern) és a szöveg aktuális ablakának hash-értékét számolja ki.
- A hash-értékek gyorsan újraszámíthatók az ablakok között.
- Összehasonlítás:
- Ha a hash-értékek egyeznek, a mintát és a szövegrészt karakterenként összehasonlítja, hogy megerősítse az illeszkedést.
- Ha a hash-értékek eltérnek, az algoritmus azonnal tovább lép a következő ablakra.
- Optimalizálás:
- A Baeza-Yates-Gonnet-algoritmus hatékonyan minimalizálja az összehasonlítások számát, kihasználva a hashing mechanizmus előnyeit.
- Időkomplexitás:
- Átlagos esetben: ( O(n + m) ), ahol ( n ) a szöveg hossza és ( m ) a minta hossza.
- Legrosszabb esetben: ( O(nm) ), ha sok ütközés történik a hash-értékek között.
Algoritmus lépései
- Hash érték inicializálása:
- Számítsd ki a keresett minta hash-értékét.
- Számítsd ki a szöveg első ablakának (az első ( m ) karakter) hash-értékét.
- Keresési folyamat:
- Lépj végig a szövegen ablakokban.
- Ha a hash-értékek megegyeznek, karakterenként hasonlítsd össze a mintát az aktuális ablakkal.
- Ha illeszkedés található, jegyezd fel az aktuális pozíciót.
- Ablak frissítése:
- Használj egy gördülő hash-függvényt az új hash-érték gyors kiszámítására az előző érték alapján.
- Ismétlés:
- Haladj végig az összes lehetséges ablakon.
Python Implementáció
Az alábbi Python-kód bemutatja a Baeza-Yates-Gonnet-algoritmus működését.
def baeza_yates_gonnet(text, pattern, base=256, prime=101):
"""
Baeza-Yates-Gonnet szövegkereső algoritmus.
:param text: Szöveg, amelyben keresünk.
:param pattern: Keresett minta.
:param base: Hash alap (általában 256).
:param prime: Hash modulo értéke (általában egy prím).
:return: A minta kezdőindexei a szövegben.
"""
n = len(text)
m = len(pattern)
h = pow(base, m-1) % prime # Hash súly
p_hash = 0 # Minta hash értéke
t_hash = 0 # Szöveg hash értéke
result = []
# Kezdeti hash-értékek kiszámítása
for i in range(m):
p_hash = (base * p_hash + ord(pattern[i])) % prime
t_hash = (base * t_hash + ord(text[i])) % prime
# Keresés a szövegben
for i in range(n - m + 1):
# Hash értékek összehasonlítása
if p_hash == t_hash:
# Karakterenkénti ellenőrzés
if text[i:i+m] == pattern:
result.append(i)
# Hash frissítése az új ablakra
if i < n - m:
t_hash = (base * (t_hash - ord(text[i]) * h) + ord(text[i + m])) % prime
if t_hash < 0:
t_hash += prime
return result
# Példa használat
text = "ababcabcabc"
pattern = "abc"
matches = baeza_yates_gonnet(text, pattern)
print(f"Minta megtalálva a következő indexeken: {matches}")
Kimenet:
Minta megtalálva a következő indexeken: [2, 5, 8]
C++ Implementáció
Az alábbi C++-kód a Baeza-Yates-Gonnet-algoritmus egy egyszerű változatát mutatja be.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
vector<int> baezaYatesGonnet(const string& text, const string& pattern, int base = 256, int prime = 101) {
int n = text.size();
int m = pattern.size();
int h = 1; // Hash súly
for (int i = 0; i < m - 1; i++) {
h = (h * base) % prime;
}
int p_hash = 0; // Minta hash
int t_hash = 0; // Szöveg hash
vector<int> result;
// Kezdeti hash-értékek
for (int i = 0; i < m; i++) {
p_hash = (base * p_hash + pattern[i]) % prime;
t_hash = (base * t_hash + text[i]) % prime;
}
// Keresés
for (int i = 0; i <= n - m; i++) {
if (p_hash == t_hash) {
if (text.substr(i, m) == pattern) {
result.push_back(i);
}
}
// Hash frissítése
if (i < n - m) {
t_hash = (base * (t_hash - text[i] * h) + text[i + m]) % prime;
if (t_hash < 0) {
t_hash += prime;
}
}
}
return result;
}
int main() {
string text = "ababcabcabc";
string pattern = "abc";
vector<int> matches = baezaYatesGonnet(text, pattern);
cout << "Minta megtalálva a következő indexeken: ";
for (int index : matches) {
cout << index << " ";
}
cout << endl;
return 0;
}
Kimenet:
Minta megtalálva a következő indexeken: 2 5 8
Magyarázat
- Hashing:
- Az algoritmus gördülő hash-t használ, amely hatékonyan frissíti az aktuális ablak hash-értékét anélkül, hogy újra kiszámolná minden karakterre.
- Összehasonlítások:
- A hash-értékek gyors szűrőként működnek, és csökkentik az explicit összehasonlítások számát.
- Előnyök:
- Hatékony nagy szövegekben, különösen akkor, ha kevés ütközés fordul elő a hash-értékek között.
- Hátrányok:
- Ha a hash-függvény nem elég jó, sok ütközés történhet, ami lassítja az algoritmust.
Alkalmazások
- Szövegfeldolgozás:
- Nagy dokumentumokban substringek gyors keresése.
- DNS-keresések:
- DNS-szekvenciák gyors illesztése.
- Adatbázisok:
- Szöveges adatok gyors keresése adatbázisokban.
Ez az algoritmus egyszerűbb implementációval és hatékony hash-alapú mechanizmussal dolgozik, amely hasznos, ha gyors substring keresésre van szükség.
Fordítások
- Baeza-Yates-Gonnet-algoritmus - Értelmező szótár (MEK)
- Baeza-Yates-Gonnet-algoritmus - Etimológiai szótár (UMIL)
- Baeza-Yates-Gonnet-algoritmus - Szótár.net (hu-hu)
- Baeza-Yates-Gonnet-algoritmus - DeepL (hu-de)
- Baeza-Yates-Gonnet-algoritmus - Яндекс (hu-ru)
- Baeza-Yates-Gonnet-algoritmus - Google (hu-en)
- Baeza-Yates-Gonnet-algoritmus - Helyesírási szótár (MTA)
- Baeza-Yates-Gonnet-algoritmus - Wikidata
- Baeza-Yates-Gonnet-algoritmus - Wikipédia (magyar)