leghosszabb közös részsorozat
Kiejtés
- IPA: [ ˈlɛkhosːɒbː ˈkøzøʃ ˈreːʃːorozɒt]
Főnév
Leghosszabb közös részsorozat (LCS - Longest Common Subsequence)
A leghosszabb közös részsorozat (LCS) egy olyan probléma, amely két sorozat (vagy sztring) közös részhalmazának legnagyobb hosszúságú, sorrendet megőrző részsorozatát keresi. A részsorozat olyan elemek sorozata, amelyek nem feltétlenül szomszédosak, de a sorrendjük megegyezik az eredeti sorozatokban.
Probléma meghatározása
Bemenet:
- Két sztring vagy sorozat: (X = x_1, x_2, …, x_m) és (Y = y_1, y_2, …, y_n).
Kimenet:
- Egy (Z = z_1, z_2, …, z_k) részsorozat, ahol:
- (Z) mindkét sorozat részsorozata.
- (Z) a lehető leghosszabb.
Algoritmus
A probléma megoldására a dinamikus programozás technikáját használjuk. Az alapötlet az, hogy egy táblázatban ((dp)) tároljuk az (LCS(X[1..i], Y[1..j])) értékét, azaz az (X) első (i) karakterének és a (Y) első (j) karakterének leghosszabb közös részsorozatát.
Lépések
- Táblázat inicializálása:
- Hozz létre egy ((m+1) (n+1))-es táblázatot, ahol (m) és (n) az (X) és (Y) hosszai.
- Az első sor és oszlop értékei nullák ((dp[0][j] = dp[i][0] = 0)), mert az üres sztringnek nincs közös részsorozata más sztringgel.
- Rekurzív kapcsolat:
- Ha (X[i] = Y[j]), akkor: [ dp[i][j] = dp[i-1][j-1] + 1 ]
- Ha (X[i] Y[j]), akkor: [ dp[i][j] = (dp[i-1][j], dp[i][j-1]) ]
- Táblázat kitöltése:
- Iteratívan töltsd ki a táblázatot a fenti szabályok alapján.
- LCS visszafejtése:
- A (dp[m][n]) érték adja a leghosszabb közös részsorozat hosszát.
- A táblázatot visszafelé követve rekonstruálható a közös részsorozat.
Idő- és tárkomplexitás
- Időbonyolultság: (O(m n)), ahol (m) és (n) a két sztring hossza.
- Tárbonyolultság: (O(m n)) a táblázat tárolásához.
Ha csak a hosszra van szükség, a tárbonyolultság csökkenthető (O(n))-re.
Pszeudokód
function LCS(X, Y): m = len(X) n = len(Y) dp = [[0] * (n + 1) for _ in range(m + 1)] for i in range(1, m + 1): for j in range(1, n + 1): if X[i - 1] == Y[j - 1]: dp[i][j] = dp[i - 1][j - 1] + 1 else: dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) # LCS visszafejtése i, j = m, n lcs = [] while i > 0 and j > 0: if X[i - 1] == Y[j - 1]: lcs.append(X[i - 1]) i -= 1 j -= 1 elif dp[i - 1][j] > dp[i][j - 1]: i -= 1 else: j -= 1 return ''.join(reversed(lcs))
Python implementáció
def lcs(X, Y):
m, n = len(X), len(Y)
dp = [[0] * (n + 1) for _ in range(m + 1)]
# Táblázat kitöltése
for i in range(1, m + 1):
for j in range(1, n + 1):
if X[i - 1] == Y[j - 1]:
dp[i][j] = dp[i - 1][j - 1] + 1
else:
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
# LCS visszafejtése
i, j = m, n
lcs = []
while i > 0 and j > 0:
if X[i - 1] == Y[j - 1]:
lcs.append(X[i - 1])
i -= 1
j -= 1
elif dp[i - 1][j] > dp[i][j - 1]:
i -= 1
else:
j -= 1
return ''.join(reversed(lcs))
# Példa használat
X = "AGGTAB"
Y = "GXTXAYB"
print("Leghosszabb közös részsorozat:", lcs(X, Y))
Kimenet:
Leghosszabb közös részsorozat: GTAB
C++ implementáció
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
string lcs(const string& X, const string& Y) {
int m = X.size(), n = Y.size();
vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));
// Táblázat kitöltése
for (int i = 1; i <= m; ++i) {
for (int j = 1; j <= n; ++j) {
if (X[i - 1] == Y[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
// LCS visszafejtése
string lcs = "";
int i = m, j = n;
while (i > 0 && j > 0) {
if (X[i - 1] == Y[j - 1]) {
lcs += X[i - 1];
--i;
--j;
} else if (dp[i - 1][j] > dp[i][j - 1]) {
--i;
} else {
--j;
}
}
reverse(lcs.begin(), lcs.end());
return lcs;
}
int main() {
string X = "AGGTAB";
string Y = "GXTXAYB";
cout << "Leghosszabb közös részsorozat: " << lcs(X, Y) << endl;
return 0;
}
Kimenet:
Leghosszabb közös részsorozat: GTAB
Alkalmazások
- Bioinformatika:
- DNS-szekvenciák összehasonlítása.
- Szövegfeldolgozás:
- Dokumentumok közötti hasonlóság mérése.
- Verziókezelés:
- Kódváltoztatások összehasonlítása.
- Adatkompresszió:
- Redundancia csökkentése.
Összegzés
A LCS-algoritmus hatékony és egyszerű módszer a szövegek vagy sorozatok hasonlóságának meghatározására. Bár tárigénye nagyobb, mint egyes alternatív megoldásoké, robusztussága és sokoldalúsága miatt széles körben alkalmazzák a számítástechnikában és a tudományban.
Fordítások
- leghosszabb közös részsorozat - Értelmező szótár (MEK)
- leghosszabb közös részsorozat - Etimológiai szótár (UMIL)
- leghosszabb közös részsorozat - Szótár.net (hu-hu)
- leghosszabb közös részsorozat - DeepL (hu-de)
- leghosszabb közös részsorozat - Яндекс (hu-ru)
- leghosszabb közös részsorozat - Google (hu-en)
- leghosszabb közös részsorozat - Helyesírási szótár (MTA)
- leghosszabb közös részsorozat - Wikidata
- leghosszabb közös részsorozat - Wikipédia (magyar)