C # перевод текстового файла с вкладками в дерево

#c# #file #tree

#c# #файл #дерево

Вопрос:

У меня есть текстовый файл со списком вкладок, который нужно превратить в дерево.

Содержимое файла:

 root
    node1
    node2
        node2_1
    node3
        node3_1
        node3_2
            node3_2_1
    node4   
  

Дерево должно выглядеть так:

                 root          
    /     |                
  node1 node2      node3     node4
          |      /       
        node2_1 node3_1  node3_2
                           
                          node3_2_1
  

Я пытаюсь создать рекурсивный метод для создания дерева, но не уверен, как отслеживать родительский и корневой.

Комментарии:

1. Как вы сейчас анализируете дерево?

Ответ №1:

Предполагая, что ваш класс узла выглядит следующим образом:

 public class Node
{
    public Node(string value)
    {
        Value = value;
        Children = new List<Node>();
    }

    public string Value { get; }

    public List<Node> Children{ get; }
}
  

Вы можете попробовать этот метод, чтобы получить дерево (при условии, что ваш ввод соответствует тому, что вы опубликовали, а корень — первая строка):

 public Node GetTree(string filePath)
{
    string[] lines = System.IO.File.ReadAllLines(filePath);

    //if lines is empty the tree is null
    if(lines.Length == 0)
    {
        return null;
    }

    //create the root
    Node root = new Node(lines[0].Trim());

    //get the root leading white spaces length
    int rootWhiteSpaceLength = lines[0].TakeWhile(c => c=" ").Count();

    //Crete  a list to hold the nodes and their white space length
    List<Tuple<Node, int>> nodesAndLengths = new  List<Tuple<Node, int>>();

    //add the root to nodes list with it's white space length
    nodesAndLengths.Add(new Tuple<Node, int>(root, rootWhiteSpaceLength));       

    //iterate over the lines strating from index 1
    for (var i = 1; i < lines.Length, i  )
    {
        //create the node
        Node node = new Node(lines[i].Trim());

        //get the node leading white spaces length
        int nodeWhiteSpaceLength = lines[i].TakeWhile(c => c=" ").Count();

        //Check that is not another root
        if(nodeWhiteSpaceLength <= rootWhiteSpaceLength)
        {
            throw new Exception("There is more than one root");
        }

        //find the node parent in the nodes list using LINQ
        Node parent = nodesAndLengths.Last(nodeAndLength => nodeAndLength.Item2 < nodeWhiteSpaceLength).Item1;

        //Alternatively using while loop
        //int j = i - 1;
        //while(nodeWhiteSpaceLength >= nodesAndLengths[j].Item2)
        //{
            //j--;
        //}
        //Node parent=nodesAndLengths[j].Item1;

        //add the node to it's parent
        parent.Children.Add(node);

        //add the node to nodes list with it's white space length
        nodesAndLengths.Add(New Tuple<Node, int>(node, nodeWhiteSpaceLength));
    }

    return root; 
}