diff options
| author | Gloria Mundi <gloria@gloria-mundi.eu> | 2024-11-16 01:24:14 +0100 |
|---|---|---|
| committer | Gloria Mundi <gloria@gloria-mundi.eu> | 2024-11-16 01:24:14 +0100 |
| commit | 98567ec798aa8ca2cfbcb85c774dd470f30e30d4 (patch) | |
| tree | 5113d5cc24d1ad5f93810b6442ce584a36950dc8 /content/string/suffixTree.cpp | |
| parent | ad3856a6b766087df0036de0b556f4700a6498c9 (diff) | |
| parent | 8d11c6c8213f46f0fa19826917c255edd5d43cb1 (diff) | |
mzuenni tests
Diffstat (limited to 'content/string/suffixTree.cpp')
| -rw-r--r-- | content/string/suffixTree.cpp | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/content/string/suffixTree.cpp b/content/string/suffixTree.cpp new file mode 100644 index 0000000..7112f39 --- /dev/null +++ b/content/string/suffixTree.cpp @@ -0,0 +1,72 @@ +struct SuffixTree { + struct Vert { + int start, end, suf; //s[start...end) along parent edge + map<char, int> nxt; + }; + string s; + int needsSuffix, pos, remainder, curVert, curEdge, curLen; + // Each Vertex gives its children range as [start, end) + vector<Vert> tree = {Vert{-1, -1, 0, {}}}; + + SuffixTree(const string& s_) : s(s_) { + needsSuffix = remainder = curVert = curEdge = curLen = 0; + pos = -1; + for (int i = 0; i < sz(s); i++) extend(); + } + + int newVert(int start, int end) { + tree.push_back({start, end, 0, {}}); + return sz(tree) - 1; + } + + void addSuffixLink(int vert) { + if (needsSuffix) tree[needsSuffix].suf = vert; + needsSuffix = vert; + } + + bool fullImplicitEdge(int vert) { + int len = min(tree[vert].end, pos + 1) - tree[vert].start; + if (curLen >= len) { + curEdge += len; + curLen -= len; + curVert = vert; + return true; + } else { + return false; + }} + + void extend() { + pos++; + needsSuffix = 0; + remainder++; + while (remainder) { + if (curLen == 0) curEdge = pos; + if (!tree[curVert].nxt.count(s[curEdge])) { + int leaf = newVert(pos, sz(s)); + tree[curVert].nxt[s[curEdge]] = leaf; + addSuffixLink(curVert); + } else { + int nxt = tree[curVert].nxt[s[curEdge]]; + if (fullImplicitEdge(nxt)) continue; + if (s[tree[nxt].start + curLen] == s[pos]) { + curLen++; + addSuffixLink(curVert); + break; + } + int split = newVert(tree[nxt].start, + tree[nxt].start + curLen); + tree[curVert].nxt[s[curEdge]] = split; + int leaf = newVert(pos, sz(s)); + tree[split].nxt[s[pos]] = leaf; + tree[nxt].start += curLen; + tree[split].nxt[s[tree[nxt].start]] = nxt; + addSuffixLink(split); + } + remainder--; + if (curVert == 0 && curLen) { + curLen--; + curEdge = pos - remainder + 1; + } else { + curVert = tree[curVert].suf ? tree[curVert].suf : 0; + }}} +};
\ No newline at end of file |
