Skip to content

Commit

Permalink
Fix encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexeyDmitriev committed Oct 19, 2013
1 parent fe00fab commit 4b6544f
Showing 1 changed file with 45 additions and 45 deletions.
90 changes: 45 additions & 45 deletions suffixArray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,22 @@ using namespace std;
void Build(const string& init, vector <int>& suffArray, vector <int>& lcp) {
string s = init;
s.push_back(char(0));
/*çäåñü áóäóò õðàíèòüñÿ èíäåêñû ïåðâûõ ýëåìåíòîâ êëàññîâ â ñóôôèêñíîì ìàññèâå ïîñëå ñîðòèðîâêè ïî 1-ìó ñèìâîëó*/
/*здесь будут храниться индексы первых элементов классов в суффиксном массиве после сортировки по 1-му символу*/
vector <int> head;
/*color[i] - êëàññ ñóôôèêñà, íà÷èíàþùåãîñÿ ñ i-ãî ñèìâîëà*/
/*color[i] - класс суффикса, начинающегося с i-го символа*/
vector <int> color;
/*òî æå, ÷òî è color, áóäåò èñïîëüçîâàòüñÿ âî âðåìÿ ñîðòèðîâêè*/
/*то же, что и color, будет использоваться во время сортировки*/
vector <int> colorSub;
vector <int> suffArraySub;
/*256 - ìàêñèìàëüíûé ñèìâîë àëôàâèòà*/
/*256 - максимальный символ алфавита*/
head.assign(max((int)s.size(), 256), 0);
suffArray.resize(s.size());
color.resize(s.size());
colorSub.resize(s.size());
suffArraySub.resize(s.size());
lcp.resize(s.size());

/*âûïîëíÿåì ñîðòèðîâêó ñóôôèêñîâ ïî ïåðâîìó ñèìâîëó*/
/*выполняем сортировку суффиксов по первому символу*/
for (int i = 0; i < s.size(); ++i) {
++head[s[i]];
}
Expand All @@ -41,9 +41,9 @@ void Build(const string& init, vector <int>& suffArray, vector <int>& 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) {
Expand All @@ -54,9 +54,9 @@ void Build(const string& init, vector <int>& suffArray, vector <int>& 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;
Expand All @@ -68,7 +68,7 @@ void Build(const string& init, vector <int>& suffArray, vector <int>& lcp) {
}
suffArray = suffArraySub;

/*ñòðîèì color è head*/
/*строим color и head*/
int secondPartBeginning;
pair <int, int> prevSuffClasses, curSuffClasses;
curSuffClasses = make_pair(-1, 0);
Expand All @@ -92,13 +92,13 @@ void Build(const string& init, vector <int>& suffArray, vector <int>& lcp) {

color = colorSub;

/*åñëè ÷èñëî êëàññîâ äîñòèãëî êîëè÷åñòâà ñóôôèêñîâ -> â suffArray ïðàâèëüíûé ñóôôìàññèâ*/
/*если число классов достигло количества суффиксов -> в suffArray правильный суффмассив*/
if (numberOfClasses == s.size())
break;
}

/*àëãîðèòì Êàñàè äëÿ ïîñòðîåíèÿ lcp*/
/*pos[i] - ïîçèöèÿ ñóôôèêñà, íà÷èíàþùåãîñÿ ñ ñèìâîëà i â suffArray*/
/*алгоритм Касаи для построения lcp*/
/*pos[i] - позиция суффикса, начинающегося с символа i в suffArray*/
vector <int> pos;
int curLcp = 0;
pos.resize(s.size());
Expand All @@ -124,7 +124,7 @@ void Build(const string& init, vector <int>& suffArray, vector <int>& 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()) {
Expand All @@ -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 <int>& a, vector < vector <int> >& sparseTable, vector <int>& precalc) {
precalc.resize(a.size() + 1);
precalc[1] = precalc[0] = 0;
Expand Down Expand Up @@ -173,80 +173,80 @@ int GetMin(int l, int r, const vector < vector <int> >& 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 <int>& suffArray,
const vector < vector <int> >& sparseTable, const vector <int>& precalc, vector <int>& 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;
}
Expand All @@ -256,7 +256,7 @@ void find(const string& s, const string& t, const vector <int>& 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;
Expand Down Expand Up @@ -336,4 +336,4 @@ int main() {
cout << endl;
}
return 0;
}
}

0 comments on commit 4b6544f

Please sign in to comment.