diff --git a/suffixArray.cpp b/suffixArray.cpp index c962a43..73bf78c 100644 --- a/suffixArray.cpp +++ b/suffixArray.cpp @@ -11,14 +11,14 @@ using namespace std; void Build(const string& init, vector & suffArray, vector & lcp) { string s = init; s.push_back(char(0)); - /* 1- */ + /*здесь будут храниться индексы первых элементов классов в суффиксном массиве после сортировки по 1-му символу*/ vector head; - /*color[i] - , i- */ + /*color[i] - класс суффикса, начинающегося с i-го символа*/ vector color; - /* , color, */ + /*то же, что и color, будет использоваться во время сортировки*/ vector colorSub; vector suffArraySub; - /*256 - */ + /*256 - максимальный символ алфавита*/ head.assign(max((int)s.size(), 256), 0); suffArray.resize(s.size()); color.resize(s.size()); @@ -26,7 +26,7 @@ void Build(const string& init, vector & suffArray, vector & lcp) { suffArraySub.resize(s.size()); lcp.resize(s.size()); - /* */ + /*выполняем сортировку суффиксов по первому символу*/ for (int i = 0; i < s.size(); ++i) { ++head[s[i]]; } @@ -41,9 +41,9 @@ void Build(const string& init, vector & suffArray, vector & lcp) { suffArray[head[s[i]]] = i; ++head[s[i]]; } - /* suffArray */ + /*в suffArray суффиксы отсортированы по первому символу*/ - /* , head , */ + /*разбиваем суффиксы на классы, приводим head к определению, данному в начале*/ int numberOfClasses = 1; head[0] = 0; for (int i = 1; i < s.size(); ++i) { @@ -54,9 +54,9 @@ void Build(const string& init, vector & suffArray, vector & lcp) { color[suffArray[i]] = numberOfClasses - 1; } - /**/ + /*сортировка*/ for (int k = 1; k < s.size(); k *= 2) { - /* 2*k*/ + /*сортировка по подстрокам длины 2*k*/ for (int i = 0; i < s.size(); ++i) { int firstPartBeginning = suffArray[i] - k; @@ -68,7 +68,7 @@ void Build(const string& init, vector & suffArray, vector & lcp) { } suffArray = suffArraySub; - /* color head*/ + /*строим color и head*/ int secondPartBeginning; pair prevSuffClasses, curSuffClasses; curSuffClasses = make_pair(-1, 0); @@ -92,13 +92,13 @@ void Build(const string& init, vector & suffArray, vector & lcp) { color = colorSub; - /* -> suffArray */ + /*если число классов достигло количества суффиксов -> в suffArray правильный суффмассив*/ if (numberOfClasses == s.size()) break; } - /* lcp*/ - /*pos[i] - , i suffArray*/ + /*алгоритм Касаи для построения lcp*/ + /*pos[i] - позиция суффикса, начинающегося с символа i в suffArray*/ vector pos; int curLcp = 0; pos.resize(s.size()); @@ -124,7 +124,7 @@ void Build(const string& init, vector & suffArray, vector & lcp) { } } -/* lcp a aShift b bShift*/ +/*нахождение lcp для строки a со сдвигом aShift и строки b со сдвигом bShift*/ int GetBruteLcp(const string& a, int aShift, const string& b, int bShift) { for (int i = 0;;++i) { if (i + aShift == a.size()) { @@ -139,8 +139,8 @@ int GetBruteLcp(const string& a, int aShift, const string& b, int bShift) { } } -/* sparse table */ -/* precalc: precalc[i] - <= i*/ +/*построение sparse table по минимуму для вектора а*/ +/*в precalc: precalc[i] - максимальная степень двойки <= i*/ void BuildSparseTable(const vector & a, vector < vector >& sparseTable, vector & precalc) { precalc.resize(a.size() + 1); precalc[1] = precalc[0] = 0; @@ -173,80 +173,80 @@ int GetMin(int l, int r, const vector < vector >& sparseTable, const vecto return min(sparseTable[l][precalc[r - l + 1]], sparseTable[r - (1 << precalc[r - l + 1]) + 1][precalc[r - l + 1]]); } -/* t s*/ -/* suffArray - s*/ -/* sparseTable lcp suffArray*/ -/* precalc sparseTable*/ -/* positions - t s*/ +/* нахождение всех вхождений строки t в строку s*/ +/* suffArray - суфф массив по s*/ +/* sparseTable по lcp для suffArray*/ +/* precalc для sparseTable*/ +/* в positions - начала всех вхождений t в s*/ void find(const string& s, const string& t, const vector & suffArray, const vector < vector >& sparseTable, const vector & precalc, vector & positions) { - /* 2 : , t - , t*/ + /*будем делать 2 бинпоиска: первый для нахождения минимального суффикса, начинающегося с t + второй для нахождения максимального суффикса, начинающегося с t*/ int leftBorder, rightBorder; - /*leftBorder - , t, */ - /*rightBorder - , t, */ + /*leftBorder - позиция минимального суффикса, начинающегося с t, в суффмассиве*/ + /*rightBorder - позиция максимального суффикса, начинающегося с t, в суффмассиве*/ int l = 0; int r = suffArray.size() - 1; - /*mlrLeft - lcp t */ - /*mlrRight - lcp t */ + /*mlrLeft - lcp строки t и минимального суффикса*/ + /*mlrRight - lcp строки t и максимального суффикса*/ int mlrLeft = GetBruteLcp(s, suffArray.front(), t, 0); int mlrRight = GetBruteLcp(s, suffArray.back(), t, 0); - /* */ + /*первый бинпоиск*/ while (true) { if (mlrLeft == t.size()) { - /* */ + /*значит нашли ответ*/ leftBorder = l; break; } if (l == r) { - /* t*/ + /*значит ни один суффикс не начинается с t*/ return ; } if (l == r - 1) { if (mlrRight == t.size()) { - /* */ + /*значит нашли ответ*/ leftBorder = r; break; } else { - /* t*/ + /*значит ни один суффикс не начинается с t*/ return ; } } - /* middle != l middle != r*/ + /*теперь middle != l и middle != r*/ int middle = (l + r) / 2; - /*lcpLeftMiddle - lcp , l suffArray, - , middle suffArray*/ - /*lcpRightMiddle - lcp , r suffArray, - , middle suffArray*/ + /*lcpLeftMiddle - lcp суффикса, находящегося на позиции l в suffArray, + и суффикса, находящегося на позиции middle в suffArray*/ + /*lcpRightMiddle - lcp суффикса, находящегося на позиции r в suffArray, + и суффикса, находящегося на позиции middle в suffArray*/ int lcpLeftMiddle = GetMin(l, middle, sparseTable, precalc); int lcpRightMiddle = GetMin(middle, r, sparseTable, precalc); - /*mlrMiddle - lcp t , middle suffArray*/ + /*mlrMiddle - lcp строки t и суффикса, находящегося на позиции middle в suffArray*/ int mlrMiddle = max(min(lcpLeftMiddle, mlrLeft), min(lcpRightMiddle, mlrRight)); - /*, , */ + /*но, возможно, его можно увеличить*/ mlrMiddle += GetBruteLcp(s, suffArray[middle] + mlrMiddle, t, mlrMiddle); if (mlrMiddle == t.size()) { - /* l middle*/ + /*тогда ответ может находиться только между l и middle*/ r = middle; mlrRight = mlrMiddle; continue; } - /*less = true, , middle suffArray, t*/ + /*less = true, если суффикс, находящегося на позиции middle в suffArray, меньше строки t*/ bool less = false; if (suffArray[middle] + mlrMiddle == s.size() || s[suffArray[middle] + mlrMiddle] < t[mlrMiddle]) { less = true; } if (less) { - /* middle r*/ + /*тогда нужно искать между middle и r*/ l = middle; mlrLeft = mlrMiddle; } else { - /* l middle*/ + /*тогда нужно искать между l и middle*/ r = middle; mlrRight = mlrMiddle; } @@ -256,7 +256,7 @@ void find(const string& s, const string& t, const vector & suffArray, r = suffArray.size() - 1; mlrLeft = GetBruteLcp(s, suffArray.front(), t, 0); mlrRight = GetBruteLcp(s, suffArray.back(), t, 0); - /* */ + /*второй бинпоиск*/ while (true) { if (mlrRight == t.size()) { rightBorder = r; @@ -336,4 +336,4 @@ int main() { cout << endl; } return 0; -} \ No newline at end of file +}