Skip to content

Commit 5b1a83a

Browse files
committed
add Lyndon Word Factorization
1 parent 3348d5d commit 5b1a83a

File tree

5 files changed

+118
-1
lines changed

5 files changed

+118
-1
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ Collections of some commonly used algorithms.
1717
+ [x] 后缀自动机
1818
+ [ ] 子序列自动机
1919
+ [ ] AC自动机
20-
+ [x] Minimum Palindromic Factorization
20+
+ [x] Palindromic Factorization
21+
+ [x] Lyndon Word Factorization
2122
+ [ ] Square Factorization
2223
+ [ ] Repetitions
2324

File renamed without changes.
File renamed without changes.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#include <vector>
2+
#include <string>
3+
#include <cstring>
4+
5+
/**
6+
* Duval's Lyndon Factorization Algorithm.
7+
*
8+
* the input string s should end with a zero symbol
9+
* return a list of begins of prime strings
10+
**/
11+
std::vector<int> duval(char s[]){
12+
std::vector<int> ret;
13+
int n = strlen(s) + 1; // zero used here
14+
int start = 0, mid = 1, cur = 0;
15+
ret.push_back(0);
16+
for (int i = 0; i < n; ++i){
17+
if (s[i] == s[cur]){
18+
if (++cur == mid) cur = start;
19+
} else if (s[i] > s[cur]){
20+
mid = i + 1;
21+
cur = start;
22+
} else if (s[i] < s[cur]){
23+
int temp = mid - start;
24+
while (start + temp <= i){
25+
start += temp;
26+
ret.push_back(start);
27+
}
28+
i = cur = start;
29+
mid = start + 1;
30+
}
31+
}
32+
return ret;
33+
}
34+
35+
/**
36+
* Duval's Algorithm for Generating Lyndon Words
37+
*
38+
* generate the Lyndon words of length at most n with a given alphabet size m
39+
* in lexicographic order.
40+
**/
41+
void lyndon_generate(int n, int m) {
42+
char z = 'a' + m - 1, s[1000];
43+
s[0] = 'a' - 1;
44+
for (int i = 1, x = 1; ; ++i) {
45+
s[x - 1]++; s[x] = 0;
46+
puts(s);
47+
for (int j = x; j < n; ++j) s[j] = s[j - x];
48+
for (x = n; s[x - 1] == z; --x);
49+
}
50+
}

string-utility/suffix-tree.cc

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#include <cstring>
2+
3+
/**
4+
* Ukkonen's Online Construction of Suffix Tree
5+
**/
6+
namespace SuffixTree {
7+
static const int SIZE = 100000 + 10, SIGMA = 26, inf = 1e9;
8+
struct node {
9+
node *go[26], *link, *fa;
10+
int st, len;
11+
node() {}
12+
void clr() {
13+
st = 0, len = inf;
14+
link = fa = NULL;
15+
memset(go, 0, sizeof(go));
16+
}
17+
} pool[SIZE], *rt, *sz;
18+
19+
struct position {
20+
node *u;
21+
int pos;
22+
position() {}
23+
position(node* u, int pos): u(u), pos(pos) {}
24+
void go(int o) {u = u->go[o], pos -= u->len;}
25+
bool can(int o) {return pos > u->go[o]->len;}
26+
} last;
27+
int s[SIZE], n;
28+
node *new_node(int st, int len) {
29+
sz->clr();
30+
sz->st = st, sz->len = len;
31+
return sz++;
32+
}
33+
void init() {
34+
n = 0, sz = pool;
35+
rt = new_node(0, inf);
36+
last = position(rt, 0);
37+
}
38+
void add(int c) {
39+
s[n++] = c;
40+
last.pos++;
41+
for (node* p = rt; last.pos; ) {
42+
while (last.can(s[n - last.pos])) last.go(s[n - last.pos]);
43+
int o = s[n - last.pos];
44+
node* &v = last.u->go[o];
45+
int t = s[v == NULL ? 0 : v->st + last.pos - 1];
46+
if (v == NULL) {
47+
v = new_node(n - last.pos, inf);
48+
p->link = last.u;
49+
p = rt;
50+
} else if (t == c) {
51+
p->link = last.u;
52+
return;
53+
} else {// split edge
54+
node *u = new_node(v->st, last.pos - 1);
55+
u->go[c] = new_node(n - 1, inf);
56+
u->go[t] = v;
57+
v->st += last.pos - 1;
58+
v->len -= last.pos - 1;
59+
p->link = v = u;
60+
p = u;
61+
}
62+
if (last.u == rt) --last.pos;
63+
else last.u = last.u->link ? last.u->link : rt;
64+
}
65+
}
66+
}

0 commit comments

Comments
 (0)