Group dot-separated string to fixed format
In the input, I got the array of the next lines that represent some tree structure:
"323-060",
"323-060.040",
"323-060.040.030",
"323-060.088",
"323-060.088.020",
"323-060.010",
"323-060.010.080",
"323-060.010.080.020",
"323-060.010.080.060"
It's tree structue:
"323-060" - the root And this tree has the next hierarchy
323-060 /*rot*/
040 /*second level, full path: 323-060.040*/
030 /* third level, full path: 323-060.040.303 */
088
020
As a result, I have to get the next list grouped:
"323-060\323-060.040\323-060.040.030"
"323-060\323-060.088\323-060.088.020"
"323-060\323-060.010\323-060.010.080\323-060.010.080.020"
"323-060\323-060.010\323-060.010.080\323-060.010.080.060"
How to do it in Java ?
In the code below Node
class represents each node
in tree. buildTree()
method create the tree from input by spliting each string by dots to get parts. And HashMap
is for keeping track of nodes
by their full path. For each part we check if the node
exists in map if not we create a new one. Inside generatePaths()
method we recursively traverse tree to create expected output.
package org.example;
import java.util.*;
public class GroupString {
static class Node {
String value;
List<Node> children;
Node(String value) {
this.value = value;
this.children = new ArrayList<>();
}
}
public static void main(String[] args) {
String[] input = {
"323-060",
"323-060.040",
"323-060.040.030",
"323-060.088",
"323-060.088.020",
"323-060.010",
"323-060.010.080",
"323-060.010.080.020",
"323-060.010.080.060"
};
Node root = buildTree(input);
List<String> result = new ArrayList<>();
generatePaths(root, new ArrayList<>(), result);
for (String path : result) {
System.out.println(path);
}
}
private static Node buildTree(String[] input) {
Map<String, Node> nodeMap = new HashMap<>();
Node root = null;
for (String path : input) {
String[] parts = path.split("\\.");
StringBuilder currentPath = new StringBuilder();
Node parent = null;
for (String part : parts) {
if (currentPath.length() > 0) {
currentPath.append(".");
}
currentPath.append(part);
String key = currentPath.toString();
Node currentNode = nodeMap.getOrDefault(key, new Node(key));
nodeMap.putIfAbsent(key, currentNode);
if (parent != null) {
if (!parent.children.contains(currentNode)) {
parent.children.add(currentNode);
}
} else {
root = currentNode;
}
parent = currentNode;
}
}
return root;
}
private static void generatePaths(Node node, List<String> path, List<String> result) {
if (node == null) return;
path.add(node.value);
if (node.children.isEmpty()) {
result.add(String.join("\\", path));
} else {
for (Node child : node.children) {
generatePaths(child, new ArrayList<>(path), result);
}
}
}
}