将文本文件解析为Java树

将文本文件解析为Java树,java,Java,在作业中,我们需要解析文本文件并使用该信息绘制树。文本文件的设置如下: <1 E> <2 N> <4 A> <7 L> <12 K> </12> </7> </4> <5 J> <8 H> </8> <9 I> &l

在作业中,我们需要解析文本文件并使用该信息绘制树。文本文件的设置如下:

<1 E>
  <2 N>
    <4 A>
      <7 L>
        <12 K>
        </12> 
      </7> 
    </4> 
    <5 J>
      <8 H>
      </8> 
      <9 I>
      </9> 
    </5> 
  </2> 
  <3 F>
    <6 G>
      <10 0>
        <13 B>
        </13> 
      </10> 
      <11 C>
        <14 D>
        </14> 
        <15 M>
        </15> 
      </11> 
    </6> 
  </3> 
</1> 

其中E是根,前面列出的每个节点都是E的子节点。数字是每个节点的唯一标识符

我们已经设置了GUI,我们只需要能够解析这个文本文件。起初,我们认为唯一的ID号可以让我们构造树,但在查看之后,我们意识到这种方法只适用于二叉树。文本文件的结构方式使我们相信存在某种递归方法,但我们看不到它。在绘制之前,我们也不知道要将解析后的树信息放入什么类型的对象中

编辑:虽然我们应该包括我们以前尝试做的代码。我们很确定我们完全走错了方向,但是w/e

public String recurseTree(Node parent, int depth, File file) throws FileNotFoundException
    {
        String line = "";
        if(fileScan.hasNext())
        {
            line = fileScan.nextLine();
        }

        while(!(line.isEmpty()))
        {
            System.out.println(line);

            int tabs = 0;
            for(int i = 0; i < line.length(); i++)
            {
                if(line.substring(i, i+1).equals("\t"))
                    tabs++;

            }
            if(tabs < depth)
                break;
            Node node = new Node(line);
            if(tabs >= depth)
            {
                if(parent != null)
                {
                    //System.out.println(parent.toString());
                }
                line = recurseTree(node, tabs, file);
            }

        }
        //System.out.println(line);
        return line;
publicstringrecursetree(节点父节点、int深度、文件文件)抛出FileNotFoundException
{
字符串行=”;
if(fileScan.hasNext())
{
line=fileScan.nextLine();
}
而(!(line.isEmpty())
{
系统输出打印项次(行);
int tabs=0;
对于(int i=0;i=深度)
{
如果(父项!=null)
{
//System.out.println(parent.toString());
}
line=recurseTree(节点、选项卡、文件);
}
}
//系统输出打印项次(行);
回流线;
这是我们的节点类

private class Node
    {
        Node parent;
        Set<Node> children;
        String name;

        public Node()
        {
            this.parent = null;
            this.name = null;
            this.children = new HashSet();
        }

        public void setName(String name)
        {
            this.name = name;
        }
        public void setParent(Node parent)
        {
            this.parent = parent;
        }
        public void addChild(Node child)
        {
            children.add(child);
        }


    }
私有类节点
{
节点父节点;
设置儿童;
字符串名;
公共节点()
{
this.parent=null;
this.name=null;
this.children=newhashset();
}
公共void集合名(字符串名)
{
this.name=名称;
}
公共void setParent(节点父节点)
{
this.parent=parent;
}
公共void addChild(节点子节点)
{
添加(child);
}
}

要确定要在其中存储数据的对象类型,请首先尝试对数据是什么进行具体处理,然后您可以设计一个对象以满足这些要求。您有:

  • 具有一个根节点的数据树
  • 每个节点可以有多个子节点
  • 每个节点都有一个数字ID和一个字符串名称
因此,直接翻译很简单:

class TreeNode {
   List<TreeNode> children; // each node can have more than one child
   int id; // each node has a numeric ID
   String name; // each node has a string name
}
(编辑:请注意,
集合
也可用于存储子项;在您的情况下,本质上是相同的。我只是默认为
列表
,原因与此无关。)

下一步是确定您需要能够执行哪些功能:

  • 需要能够在给定ID和名称的情况下创建新节点
  • 需要能够将子节点添加到现有节点
  • 需要能够获取节点的ID和名称
  • 需要能够获取节点的子节点
当然,我不会为你做你的工作,所以我不会给你这方面的代码——但重点是,首先确定你的需求,然后你可以设计匹配的代码

此时,您将有一个可用的
TreeNode
数据结构可供使用。现在您可以集中精力从文件加载数据。为此,这是一个与上述类似的过程:确定您的需求,然后实施

首先,我将尝试具体确定输入文件的结构:

  • 节点以
    开头
  • 节点启动后,可以存在任意数量的子节点
  • 节点以
    结尾
换言之:

NODE = <id name> NODE* </id>
NODE=NODE*
现在试着想想如何从中构建一棵树:

  • 读取一个
    标记并从中构造一个新的
    树节点
  • 使用相同的步骤读取任何内部节点并将其作为子节点添加
  • 读取
    时停止
这非常适合于递归方法,我相信,一旦实现了通用的
TreeNode
数据结构并具体描述了文件格式,就可以解决这个问题


顺便说一句,您可能会惊讶地注意到(只是快速评论您刚刚发布的代码)如上所述,在加载文件的过程中,您不需要跟踪树的深度。

非常感谢您的响应。我们已经编写了一个节点类。我们还考虑创建一个链表来表示树。我们节点类的代码是:链表用于列表。树通常不是列表(尽管每个节点可能都有子节点列表)。您的数据结构应该反映数据的性质。每个节点都应该包含对所有子节点的引用列表,并且您只需要在外部存储根节点(所有子节点最终都可以通过根节点访问)@user3430902出于对g*d的热爱,请不要尝试将代码粘贴到注释中。至少使用或。对我来说,这听起来像是一个链表。我们认为你可以将头部作为树的根,然后每个节点将包含一组子节点。这很接近。链表本质上是一棵树,每个节点只能有一个子节点。例如,链表有列表中第n个项目的概念,而树没有
NODE = <id name> NODE* </id>