将文本文件解析为Tree Java

时间:2014-03-17 22:40:47

标签: java

处理我们需要解析文本文件并使用该信息绘制树的任务。文本文件的设置如下:

<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号将允许我们构造树,但在看了之后我们意识到这种方法只适用于二叉树。文本文件的结构方式使我们相信有一些递归方法,但我们无法看到它。我们也不知道在绘制之前我们想要将解析后的树信息放入哪种对象。

编辑:虽然我们应该包含我们之前尝试做的代码。我们非常确定我们完全走错了轨道,但是没有。

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;

这是我们的节点类

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


    }

1 个答案:

答案 0 :(得分:2)

要确定要存储数据的对象类型,首先尝试获取有关数据的具体句柄,然后设计一个对象以满足这些要求。你有:

  • 具有一个根节点的数据树。
  • 每个节点可以有多个孩子。
  • 每个节点都有一个数字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
}

当然,其他地方:

TreeNode root; // the single root node.

(编辑:请注意,Set<TreeNode>也可用于存储儿童;在您的情况下,它基本相同。我只是默认为List,原因不是这里特别相关。)

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

  • 需要能够在给定ID和名称的情况下创建新节点。
  • 需要能够将子项添加到现有节点。
  • 需要能够获取节点的ID和名称。
  • 需要能够获得节点的孩子。

我当然不打算为你工作,所以我不打算给你代码 - 但关键是,首先确定你的要求,然后你可以设计代码到匹配。

此时,您将拥有可用的TreeNode数据结构。 现在您已准备好专注于从文件加载数据。为此,它与上述类似的过程:确定您的要求,然后实施。

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

  • 节点以<ID NAME>开头。
  • 节点启动后可能存在任意数量的子节点。
  • 节点以</ID>结尾。

换句话说:

NODE = <id name> NODE* </id>

现在尝试思考如何构建一个树:

  • 阅读<ID NAME>令牌并从中构建新的TreeNode
  • 使用相同的步骤读取所有内部节点并将其添加为子节点。
  • 阅读</ID>时停止。

这非常适合递归方法,我相信一旦实现了通用TreeNode数据结构并具体描述了您的文件格式,您将能够解决这个问题。

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