How to resolve the algorithm Eertree step by step in the Java programming language
How to resolve the algorithm Eertree step by step in the Java programming language
Table of Contents
Problem Statement
An eertree is a data structure designed for efficient processing of certain palindrome tasks, for instance counting the number of sub-palindromes in an input string. The data structure has commonalities to both tries and suffix trees. See links below.
Construct an eertree for the string "eertree", then output all sub-palindromes by traversing the tree.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Eertree step by step in the Java programming language
This code, implements an Eertree, which is a tree-like data structure used to store palindromic substrings of a given string.
1. Class Node:
- The Eertree is represented using a custom
Node
class. - Each node in the tree has three attributes:
- length: The length of the palindrome represented by the node.
- edges: A map of characters to child nodes, representing the possible extensions of the palindrome.
- suffix: The index of the suffix node, which is the longest proper suffix of the current node's palindrome.
2. Eertree Construction (eertree method):
- The
eertree
method takes a strings
as input and constructs the Eertree. - It initializes the tree with two root nodes:
- EVEN_ROOT: Represents palindromes of even length.
- ODD_ROOT: Represents palindromes of odd length.
- It iterates through the characters of the input string
s
. - For each character, it finds the longest proper suffix of the current palindrome.
- If the suffix node has an outgoing edge for the current character, it updates the suffix node to the child node.
- If the suffix node does not have an outgoing edge for the current character, it creates a new node in the tree and adds it as a child of the suffix node.
3. Finding Subpalindromes (subPalindromes method):
- The
subPalindromes
method extracts all the subpalindromes from the Eertree. - It starts from the root node and recursively traverses the tree, collecting palindromes as it goes.
- It adds palindromes to a list
s
, which is returned at the end.
Example:
For an input string "eertree", the Eertree will look like this:
EVEN_ROOT
/ \
/ \
e 0 r -1
/|\ (e) / \
/ | \ r e e
e 1 / \ \
|\| / e r e r
| | \ t t t
r 2 \ e e
|\ \ r e
| \ t t \
e 3 e \ e e 0
/|\ \ | |
/ | \ r e e |
| | \ e t | | (ODD_ROOT)
| | \ | e e |
| | \ e | | |
| | \| e e |
| | | | |
e 4 /| e e |
|\| / | | |
| | e | e e |
| | \ \ /| | |
| | \ |/ /| | |
r 5 \|/|/ /| | |
|\| /|/|/ /| | | (e)
| | /|/|/ /| /| | |
| | /|/|/ /|/|/| | | r
e 6 \|/|/|/| | | | (e)
|\| /|/|/|/| | | |
| | /|/|/|/| | | | e
e 7 \|/|/|/| | | | r
|\| /|/|/|/| | | | (e)
| |/|/|/|/| | | |
e 8 \|/|/|/| | | | e
|\| /|/|/|/| | | | (r)
| |/|/|/|/|/| | | |
e 9 \|/|/|/|/|/| | | e
|\| /|/|/|/|/|/| | | (e)
| |/|/|/|/|/|/|/|/| |
e 10 \|/|/|/|/|/|/|/|/| | (ODD_ROOT)
The subPalindromes
method will extract the following palindromes from the Eertree:
e
ee
ere
erer
eertree
Source code in the java programming language
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Eertree {
public static void main(String[] args) {
List<Node> tree = eertree("eertree");
List<String> result = subPalindromes(tree);
System.out.println(result);
}
private static class Node {
int length;
Map<Character, Integer> edges = new HashMap<>();
int suffix;
public Node(int length) {
this.length = length;
}
public Node(int length, Map<Character, Integer> edges, int suffix) {
this.length = length;
this.edges = edges != null ? edges : new HashMap<>();
this.suffix = suffix;
}
}
private static final int EVEN_ROOT = 0;
private static final int ODD_ROOT = 1;
private static List<Node> eertree(String s) {
List<Node> tree = new ArrayList<>();
tree.add(new Node(0, null, ODD_ROOT));
tree.add(new Node(-1, null, ODD_ROOT));
int suffix = ODD_ROOT;
int n, k;
for (int i = 0; i < s.length(); ++i) {
char c = s.charAt(i);
for (n = suffix; ; n = tree.get(n).suffix) {
k = tree.get(n).length;
int b = i - k - 1;
if (b >= 0 && s.charAt(b) == c) {
break;
}
}
if (tree.get(n).edges.containsKey(c)) {
suffix = tree.get(n).edges.get(c);
continue;
}
suffix = tree.size();
tree.add(new Node(k + 2));
tree.get(n).edges.put(c, suffix);
if (tree.get(suffix).length == 1) {
tree.get(suffix).suffix = 0;
continue;
}
while (true) {
n = tree.get(n).suffix;
int b = i - tree.get(n).length - 1;
if (b >= 0 && s.charAt(b) == c) {
break;
}
}
tree.get(suffix).suffix = tree.get(n).edges.get(c);
}
return tree;
}
private static List<String> subPalindromes(List<Node> tree) {
List<String> s = new ArrayList<>();
subPalindromes_children(0, "", tree, s);
for (Map.Entry<Character, Integer> cm : tree.get(1).edges.entrySet()) {
String ct = String.valueOf(cm.getKey());
s.add(ct);
subPalindromes_children(cm.getValue(), ct, tree, s);
}
return s;
}
// nested methods are a pain, even if lambdas make that possible for Java
private static void subPalindromes_children(final int n, final String p, final List<Node> tree, List<String> s) {
for (Map.Entry<Character, Integer> cm : tree.get(n).edges.entrySet()) {
Character c = cm.getKey();
Integer m = cm.getValue();
String pl = c + p + c;
s.add(pl);
subPalindromes_children(m, pl, tree, s);
}
}
}
You may also check:How to resolve the algorithm Loop over multiple arrays simultaneously step by step in the OCaml programming language
You may also check:How to resolve the algorithm Sorting algorithms/Permutation sort step by step in the Arturo programming language
You may also check:How to resolve the algorithm Cheryl's birthday step by step in the uBasic/4tH programming language
You may also check:How to resolve the algorithm Abstract type step by step in the C programming language
You may also check:How to resolve the algorithm System time step by step in the MATLAB / Octave programming language