Konstruowanie struktury drzewa z listy ścieżek łańcuchowych
Mam kolekcję ścieżek łańcuchowych takich jak ["x1/x2/x3","x1/x2/x4","x1 / x5"] w liście. Muszę skonstruować strukturę podobną do drzewa z tej listy, która może być iteracją, aby uzyskać ładne wydrukowane drzewo. like this
x1
/ \
x5 x2
/ \
x3 x4
Jakieś pomysły/sugestie? Uważam, że problem można najpierw zaatakować, przetwarzając listę edycji łańcuchów: wybrana prawidłowa odpowiedź była elegancką implementacją, inne sugestie też były dobre.
5 answers
Podążaj za implementacją naiwnej implementacji drzewa widocznego:
class Tree<T> implements Visitable<T> {
// NB: LinkedHashSet preserves insertion order
private final Set<Tree> children = new LinkedHashSet<Tree>();
private final T data;
Tree(T data) {
this.data = data;
}
void accept(Visitor<T> visitor) {
visitor.visitData(this, data);
for (Tree child : children) {
Visitor<T> childVisitor = visitor.visitTree(child);
child.accept(childVisitor);
}
}
Tree child(T data) {
for (Tree child: children ) {
if (child.data.equals(data)) {
return child;
}
}
return child(new Tree(data));
}
Tree child(Tree<T> child) {
children.add(child);
return child;
}
}
Interfaces for Visitor Pattern:
interface Visitor<T> {
Visitor<T> visitTree(Tree<T> tree);
void visitData(Tree<T> parent, T data);
}
interface Visitable<T> {
void accept(Visitor<T> visitor);
}
Przykładowa implementacja wzorca Odwiedzin:
class PrintIndentedVisitor implements Visitor<String> {
private final int indent;
PrintIndentedVisitor(int indent) {
this.indent = indent;
}
Visitor<String> visitTree(Tree<String> tree) {
return new IndentVisitor(indent + 2);
}
void visitData(Tree<String> parent, String data) {
for (int i = 0; i < indent; i++) { // TODO: naive implementation
System.out.print(" ");
}
System.out.println(data);
}
}
I wreszcie (!!!) prosty przypadek testowy:
Tree<String> forest = new Tree<String>("forest");
Tree<String> current = forest;
for (String tree : Arrays.asList("x1/x2/x3", "x1/x2/x4", "x1/x5")) {
Tree<String> root = current;
for (String data : tree.split("/")) {
current = current.child(data);
}
current = root;
}
forest.accept(new PrintIndentedVisitor(0));
Wyjście:
forest x1 x2 x3 x4 x5
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-17 12:26:15
Po prostu podziel każdą ścieżkę za pomocą ogranicznika, a następnie dodaj je do struktury drzewa jeden po drugim.
tzn. jeśli 'x1'
nie istnieje utwórz ten węzeł, jeśli istnieje przejdź do niego i sprawdź, czy istnieje potomek 'x2'
itd...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-07 04:03:34
Zrobiłbym drzewo po jednym sznurku na raz.
Stwórz puste drzewo (które ma węzeł korzeniowy - zakładam, że może być ścieżka w stylu "x7/x8/x9").
Weź pierwszy ciąg, dodaj x1 do węzła głównego, następnie x2 do x1, a następnie x3 do x2.
Weź drugi ciąg, zobacz, że x1 i x2 już tam są, dodaj x4 do x2.
Zrób to dla każdej ścieżki, którą masz.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-17 07:21:12
Utwórz węzeł obiektu, który zawiera rodzica (węzeł) i listę dzieci (węzeł).
Najpierw podziel łańcuch za pomocą",". Dla każdego podzielonego ciągu można podzielić ciąg za pomocą"/". Wyszukaj pierwszy identyfikator węzła (np. x1) na liście głównej. Jeśli możesz go znaleźć, użyj węzła, aby znaleźć następny identyfikator węzła (np. x2).
Jeśli nie możesz znaleźć węzła, dodaj go do ostatniego węzła, który udało Ci się znaleźć na istniejących listach.
Po utworzeniu listy struktura, możesz wydrukować listę na ekranie. Zrobiłbym to rekurencyjnie.
Nie testowane, tylko animacja
public void print(List nodes, int deep) {
if (nodes == null || nodes.isEmpty()) {
return;
}
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < deep; i++) {
buffer.append("---");
}
for (Iterator iterator = nodes.iterator(); iterator.hasNext();) {
Node node = (Node)iterator.next();
System.out.println(buffer.toString() + " " + node.getIdentifier());
print(node.getChildren(), deep + 1);
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-17 08:08:00
Utwórz drzewo dla każdego ciągu w tablicy. Po prostu podziel ścieżkę dla'/', sprawdź, czy węzeł istnieje w twoim drzewie, czy nie, jeśli istnieje, a następnie przejdź dalej... w przeciwnym razie utwórz nowy węzeł i dodaj go do węzła nadrzędnego.
Iteracja przy użyciu rekurencji.
Poniżej znajduje się model węzła drzewa.
Class Node{
string name;
List<Node> childrens;
Node(string name){
this.name = name;
this.childrens = new List<Node>();
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-05 15:30:48