Bu məsələdə Knut-Morris-Pratt mətn axtarış alqoritmi tətbiq edilməlidir.
Alqoritmin Tətbiqi
Aşağıdakı dəyişənləri elan edək:
— burada şablonun bütün uyğunluqları tapılmalı olan sətirdir.
— sətrində axtarılan alt sıra (şablon).
— sətrinin prefiks-funksiya dəyərlərini saxlayan massiv.
— sətrində alt sətrinin uyğunluqla başladığı bütün mövqelərin siyahısı.
string text, word;
vector<int> p, pos;MaxBorderArray funksiyası sətrinin prefiks-funksiya dəyərlərini hesablayır və onları massivinə saxlayır.
void MaxBorderArray(string &s)
{
p.resize(s.size());
for (int i = 1; i < s.size(); i++)
{
int j = p[i - 1];
while ((j > 0) && (s[i] != s[j])) j = p[j - 1];
if (s[i] == s[j]) j++;
p[i] = j;
}
}Kmp funksiyası Knut — Morris — Pratt alqoritmini həyata keçirir. sətrinin sətrindəki bütün başlanğıc indeksləri massivinə yazılır.
void kmp(string &word, string &text)
{
MaxBorderArray(word);
for (int i = 0, j = 0; i < text.size(); i++)
{
while (j && (text[i] != word[j])) j = p[j - 1];
if (text[i] == word[j]) j++;Əgər indeksinin dəyəri sətrinin son işarəsinə çatırsa, bu, sözünün tam uyğunluğunun mətndə tapıldığı deməkdir. Tətbiq olunan uyğunluğun başlanğıc mövqeyi i - j + 1-dir (işarələrin nömrələnməsi sıfırdan başlayır).
if (j == word.size()) pos.push_back(i - j + 1);
}
}Proqramın əsas hissəsi. Giriş sətirlərini oxuyuruq.
cin >> text;
cin >> word;Knut-Morris-Pratt alqoritmini işə salırıq.
kmp(word, text);Tapılan uyğunluq mövqelərini çıxarırıq.
for (auto x : pos)
cout << x << " ";
cout << endl;