Budowa DFA w algorytmie Knutha-Morrisa-Pratta
Odnoszę się do zarysu algorytmu Knutha-Morrisa-Pratta (KMP) do wyszukiwania podciągów w książce Sedgewicka "algorytmy" (4th ed.).
Algorytm KMP używa kopii zapasowej w wyszukiwaniu substringów w oparciu o deterministyczny automat skończony (Dfa). Rozumiem, jak DFA wchodzi do algorytmu, jednak nie rozumiem, jak skonstruować DFA, co odbywa się za pomocą następującego fragmentu kodu:
dfa[pat.charAt(0)][0] = 1;
for (int X = 0; j = 1; j< M; j++) {
for (int c = 0; c < R; c++) {
dfa[c][j] = dfa[c][X];
}
dfa[pat.charAt(j)][j] = j+1;
X = dfa[pat.charAt(j)][X];
}
Gdzie M
jest długością wzoru pat
i R
rozmiar alfabetu. Funkcja charAt()
Zwraca wartość całkowitą znaku na odpowiedniej pozycji.
Czy ktoś może wyjaśnić w jaki sposób ten fragment kodu konstruuje dfa? Gubię się w intuicyjnym znaczeniu wewnętrznej pętli for.
1 answers
Przyjrzyjmy się poniższemu FA dla wzoru ACACAGA.
Powyższe diagramy przedstawiają graficzne i tabelaryczne reprezentacje wzoru ACACAGA.
Tutaj liczba stanów w DFA to M + 1, Gdzie M jest długością wzoru. Najważniejszą rzeczą do skonstruowania DFA jest uzyskanie następnego stanu ze stanu bieżącego dla każdego możliwego znaku. Biorąc pod uwagę znak x i stan k, możemy uzyskać następny stan, biorąc pod uwagę ciąg " pat[0..k-1] x" czyli w zasadzie konkatenacja znaków wzorca pat [0], pat1 ... pat [k-1] i znak x. chodzi o to, aby uzyskać długość najdłuższego przedrostka danego wzoru, tak aby przedrostek był również sufiksem (LPS) "pat[0..k-1] x". Wartość długości daje nam Następny stan.
Na przykład zobaczmy, jak uzyskać następny stan z bieżącego stanu 5 i znak " C " na powyższym diagramie. Musimy wziąć pod uwagę ciąg " pat[0..5] C "czyli " ACACAC". Długość najdłuższy przedrostek wzoru taki, że przedrostek jest przyrostkiem "ACACAC" wynosi 4 ("ACAC"). Więc następny stan (ze stanu 5) to 4 dla znaku 'C'.
// dfa[i][j] = k denotes the transition function will go k'th state
// with character i from state j
// DFA will go always (i + 1)'th state from i'th state
//if the character c is equal to current character of pattern
dfa[pat.charAt(0)][0] = 1;
// here X is initialized with LPS (longest prefix suffix)
// of pattern[0....j - 1]. LPS[0] is always 0
for (int X = 0; j = 1; j< M; j++) {
for (int c = 0; c < R; c++) { // for all possible characters
// transition function from j'th state taking character c
// will go to the same state where it went from X(LPS)'th state
// taking character c (justify it with an example)
dfa[c][j] = dfa[c][X];
}
// DFA will go always (i + 1)th state from i'th state if
// the character c is equal to current character of pattern
dfa[pat.charAt(j)][j] = j + 1;
X = dfa[pat.charAt(j)][X]; // update LPS
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-30 18:00:35