Eertree: Difference between revisions
Content added Content deleted
imported>Patuitar mNo edit summary |
(Add Rust implementation) |
||
Line 1,757: | Line 1,757: | ||
{{out}} |
{{out}} |
||
<pre>["ee", "e", "r", "t", "rtr", "ertre", "eertree"]</pre> |
<pre>["ee", "e", "r", "t", "rtr", "ertre", "eertree"]</pre> |
||
=={{header|Rust}}== |
|||
{{trans|Go}} |
|||
<syntaxhighlight lang="Rust"> |
|||
use std::collections::HashMap; |
|||
use std::convert::TryInto; |
|||
struct Node { |
|||
length: isize, |
|||
edges: HashMap<u8, usize>, |
|||
suffix: usize, |
|||
} |
|||
impl Node { |
|||
fn new(length: isize, suffix: usize) -> Self { |
|||
Node { |
|||
length, |
|||
suffix, |
|||
edges: HashMap::new(), |
|||
} |
|||
} |
|||
} |
|||
const EVEN_ROOT: usize = 0; |
|||
const ODD_ROOT: usize = 1; |
|||
fn eertree(s: &[u8]) -> Vec<Node> { |
|||
let mut tree = vec![ |
|||
Node::new(0, ODD_ROOT), // even root |
|||
Node::new(-1, ODD_ROOT), // odd root |
|||
]; |
|||
let mut suffix = ODD_ROOT; |
|||
for (i, &c) in s.iter().enumerate() { |
|||
let mut n = suffix; |
|||
let mut k; |
|||
loop { |
|||
k = tree[n].length; |
|||
let k_plus_one: usize = (k + 1).try_into().unwrap_or(0); |
|||
if let Some(b) = i.checked_sub(k_plus_one) { |
|||
if b < s.len() && s[b] == c { |
|||
break; |
|||
} |
|||
} |
|||
n = tree[n].suffix; |
|||
} |
|||
if tree[n].edges.contains_key(&c) { |
|||
suffix = tree[n].edges[&c]; |
|||
continue; |
|||
} |
|||
suffix = tree.len(); |
|||
tree.push(Node::new(k + 2, 0)); |
|||
tree[n].edges.insert(c, suffix); |
|||
if tree[suffix].length == 1 { |
|||
tree[suffix].suffix = EVEN_ROOT; |
|||
continue; |
|||
} |
|||
loop { |
|||
n = tree[n].suffix; |
|||
let tree_n_length_plus_one: usize = (tree[n].length + 1).try_into().unwrap_or(0); |
|||
if let Some(b) = i.checked_sub(tree_n_length_plus_one) { |
|||
if b < s.len() && s[b] == c { |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
tree[suffix].suffix = tree[n].edges[&c]; |
|||
} |
|||
tree |
|||
} |
|||
fn sub_palindromes(tree: &[Node]) -> Vec<String> { |
|||
let mut result = Vec::new(); |
|||
fn children(node: usize, p: String, tree: &[Node], result: &mut Vec<String>) { |
|||
for (&c, &n) in &tree[node].edges { |
|||
let c = c as char; |
|||
let p_new = format!("{}{}{}", c, p, c); |
|||
result.push(p_new.clone()); |
|||
children(n, p_new, tree, result); |
|||
} |
|||
} |
|||
children(EVEN_ROOT, String::new(), tree, &mut result); |
|||
for (&c, &n) in &tree[ODD_ROOT].edges { |
|||
let c = c as char; |
|||
let p = c.to_string(); |
|||
result.push(p.clone()); |
|||
children(n, p, tree, &mut result); |
|||
} |
|||
result |
|||
} |
|||
fn main() { |
|||
let tree = eertree(b"eertree"); |
|||
let palindromes = sub_palindromes(&tree); |
|||
for palindrome in palindromes { |
|||
println!("{}", palindrome); |
|||
} |
|||
} |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
ee |
|||
e |
|||
t |
|||
rtr |
|||
ertre |
|||
eertree |
|||
r |
|||
</pre> |
|||
=={{header|Visual Basic .NET}}== |
=={{header|Visual Basic .NET}}== |