Skip to content

Commit e03b449

Browse files
author
robot
committed
suffix-array
1 parent 039fc30 commit e03b449

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed

src/codeTemplates/suffix_array.js

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
export default {
2+
title: "后缀树组",
3+
logo: "",
4+
list: [
5+
{
6+
text: "标准版",
7+
problems: [],
8+
codes: [
9+
{
10+
language: "cpp",
11+
text: `
12+
vector<int> sortCharacters(const string & text) {
13+
int n = text.size();
14+
vector<int> count(128), order(n);
15+
for (auto c : text) {
16+
count[c]++;
17+
}
18+
for (int i = 1; i < 128; i++) {
19+
count[i] += count[i - 1];
20+
}
21+
for (int i = n - 1; i >= 0; i--) {
22+
count[text[i]]--;
23+
order[count[text[i]]] = i;
24+
}
25+
return order;
26+
}
27+
28+
vector<int> computeCharClasses(const string & text, vector<int> & order) {
29+
int n = text.size();
30+
vector<int> res(n, 0);
31+
res[order[0]] = 0;
32+
for (int i = 1; i < n; i++) {
33+
if (text[order[i]] != text[order[i - 1]]) {
34+
res[order[i]] = res[order[i - 1]] + 1;
35+
} else {
36+
res[order[i]] = res[order[i - 1]];
37+
}
38+
}
39+
return res;
40+
}
41+
42+
vector<int> sortDoubled(const string & text, int len, vector<int> & order, vector<int> & classfiy) {
43+
int n = text.size();
44+
vector<int> count(n), newOrder(n);
45+
for (int i = 0; i < n; i++) {
46+
count[classfiy[i]]++;
47+
}
48+
for (int i = 1; i < n; i++) {
49+
count[i] += count[i - 1];
50+
}
51+
for (int i = n - 1; i >= 0; i--) {
52+
int start = (order[i] - len + n) % n;
53+
int cl = classfiy[start];
54+
count[cl]--;
55+
newOrder[count[cl]] = start;
56+
}
57+
return newOrder;
58+
}
59+
60+
vector<int> updateClasses(vector<int> & newOrder, vector<int> & classfiy, int len) {
61+
int n = newOrder.size();
62+
vector<int> newClassfiy(n, 0);
63+
newClassfiy[newOrder[0]] = 0;
64+
for (int i = 1; i < n; i++) {
65+
int curr = newOrder[i];
66+
int prev = newOrder[i - 1];
67+
int mid = curr + len;
68+
int midPrev = (prev + len) % n;
69+
if (classfiy[curr] != classfiy[prev] || classfiy[mid] != classfiy[midPrev]) {
70+
newClassfiy[curr] = newClassfiy[prev] + 1;
71+
} else {
72+
newClassfiy[curr] = newClassfiy[prev];
73+
}
74+
}
75+
return newClassfiy;
76+
}
77+
78+
vector<int> buildSuffixArray(const string& text) {
79+
vector<int> order = sortCharacters(text);
80+
vector<int> classfiy = computeCharClasses(text, order);
81+
int len = 1;
82+
int n = text.size();
83+
for (int i = 1; i < n; i <<= 1) {
84+
order = sortDoubled(text, i, order, classfiy);
85+
classfiy = updateClasses(order, classfiy, i);
86+
}
87+
return order;
88+
}
89+
90+
class Solution {
91+
public:
92+
string largestMerge(string word1, string word2) {
93+
int m = word1.size(), n = word2.size();
94+
string str = word1 + "@" + word2 + "*";
95+
vector<int> suffixArray = buildSuffixArray(str);
96+
vector<int> rank(m + n + 2);
97+
for (int i = 0; i < m + n + 2; i++) {
98+
rank[suffixArray[i]] = i;
99+
}
100+
101+
string merge;
102+
int i = 0, j = 0;
103+
while (i < m || j < n) {
104+
if (i < m && rank[i] > rank[m + 1 + j]) {
105+
merge.push_back(word1[i++]);
106+
} else {
107+
merge.push_back(word2[j++]);
108+
}
109+
}
110+
return merge;
111+
}
112+
};
113+
`,
114+
},
115+
],
116+
},
117+
],
118+
link: "",
119+
};

0 commit comments

Comments
 (0)