将文本文件解析为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>