Suffix tree: Difference between revisions

2,986 bytes added ,  4 years ago
add JS
(add JS)
Line 739:
</pre>
 
=={{header|JavaScript}}==
{{trans|Java}}
<lang JavaScript>class Node {
sub = ''; // a substring of the input string
children = []; // list of child nodes
}
 
class SuffixTree {
nodes = [];
 
constructor(str) {
this.nodes.push(new Node());
for (let i = 0; i < str.length; ++i) {
this.addSuffix(str.slice(i));
}
}
 
addSuffix(suf) {
let n = 0;
let i = 0;
while (i < suf.length) {
const b = suf.charAt(i);
const children = this.nodes[n].children;
let x2 = 0;
let n2;
while (true) {
if (x2 === children.length) {
// no matching child, remainder of suf becomes new node.
n2 = this.nodes.length;
const temp = new Node();
temp.sub = suf.slice(i);
this.nodes.push(temp);
children.push(n2);
return;
}
n2 = children[x2];
if (this.nodes[n2].sub.charAt(0) === b) break;
x2++;
}
// find prefix of remaining suffix in common with child
const sub2 = this.nodes[n2].sub;
let j = 0;
while (j < sub2.length) {
if (suf.charAt(i + j) !== sub2.charAt(j)) {
// split n2
const n3 = n2;
// new node for the part in common
n2 = this.nodes.length;
const temp = new Node();
temp.sub = sub2.slice(0, j);
temp.children.push(n3);
this.nodes.push(temp);
this.nodes[n3].sub = sub2.slice(j); // old node loses the part in common
this.nodes[n].children[x2] = n2;
break; // continue down the tree
}
j++;
}
i += j; // advance past part in common
n = n2; // continue down the tree
}
}
 
toString() {
if (this.nodes.length === 0) {
return '<empty>';
}
return this.toString_f(0, '');
}
 
toString_f(n, pre) {
const children = this.nodes[n].children;
if (children.length === 0) {
return '- ' + this.nodes[n].sub + '\n';
}
let s = '┐ ' + this.nodes[n].sub + '\n';
for (let i = 0; i < children.length - 1; i++) {
const c = children[i];
s += pre + '├─';
s += this.toString_f(c, pre + '│ ');
}
s += pre + '└─';
s += this.toString_f(children[children.length - 1], pre + ' ');
return s;
}
 
getLongestRepeatedSubString() {
return this.getLongestRepeatedSubString_f(0);
}
getLongestRepeatedSubString_f(n, s) {
let str = '';
if (this.nodes[n].children.length === 0) return str;
for (const n2 of this.nodes[n].children) {
const temp = this.getLongestRepeatedSubString_f(n2, str);
if (temp.length > str.length) {
str = temp;
}
}
return this.nodes[n].sub + str;
}
}
 
const st = new SuffixTree('banana');
console.log(st.toString());
console.log('>', st.getLongestRepeatedSubString());</lang>
 
{{out}}
<pre>
├─- banana
├─┐ a
│ └─┐ na
│ └─- na
└─┐ na
└─- na
 
> ana
</pre>
 
=={{header|Kotlin}}==
Anonymous user