javatreetree-structure

grouping dot-separated string list


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 ?


Solution

  • 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);
                }
            }
        }
    }