如何在Java中从字符串生成和打印树

时间:2015-06-29 21:42:39

标签: java tree pretty-print

我想从字符串中创建并打印一个从文件中读取的树。我尝试了以下代码,但无法以正确的方式打印树。

我有文件file.txt,例如以下字符串

COM-博新闻2012,12
COM-博新闻2015,3
净PHP-WWW,20
净phototrails,3个

我想创建一个像

这样的树
        root
            |
             com(17) //calculated as (2+12+3)
               |bo(17)
                  |news(17)
                       |2012 (12)
                       |2015(3)
            |net(23)
                |php(20)
                    |www(20)
                |phototrails(3)

我尝试了以下代码

public void ReadFile(String inputFile){
 Map<String[],Integer> map = new HashMap<String[], Integer>();
 BufferedReader br=null;
 String file1 = "";   
 try {
            br = new BufferedReader(new FileReader(inputFile));
            while ((file1 = br.readLine()) != null) {
                String path[]=file1.split(",");
                String nodes[]=path[0].split("-");
                map.put(nodes,Integer.parseInt(path[1].trim()));
            }
            buildTree(map);
            br.close();
        }catch(Exception e){
            System.out.println(e);
        }
}
public void buildTree(Map<String[],Integer> map)
{
    Map<String, Node> wordMap = new HashMap<String, Node>();
    Node root = new Node();

    for (Map.Entry<String[], Integer> entry : map.entrySet()) {
        String key[] = entry.getKey();
        Integer value = entry.getValue();
        Node current=root;
        Node p;
        for(String node:key)
        {

            if(wordMap.containsKey(node)){
               p = wordMap.get(node);
               p.addCost(value);

            } else {
                p=new Node(node,value);
                wordMap.put(node, p);
                System.out.println("AddNode: "+p.getName());
            }
            current.addChild(p);
            current = p;
        }

    }
    printTree(root);
}
 public  void printTree(Node doc) { ///print tree
if (doc == null) {
  System.out.println("Nothing to print!!");

  return;
}
try {
  System.out.println(doc.getName() + "  " + doc.getCount());
  List<Node> cl = doc.getChildren();
  for (int i = 0; i < cl.size(); i++) {
    Node node = cl.get(i);
    System.out.println(
      "\t" + node.getName() + " ->" + node.getCount());

  }
  List<Node> nl = doc.getChildren();
  for (int i = 0; i < nl.size(); i++) {
    Node node = nl.get(i);
    printTree(node);
  }
} catch (Throwable e) {
  System.out.println("Cannot print!! " + e.getMessage());
}
}
public class Node {

private String name;
private int count;
private List<Node> children;

public Node() {
    this(null, 0);
}

public Node(String name, int count) {
    this.name = name; 
    this.count = count;
    this.children = new ArrayList<Node>();
}

public Node(String name) {
    this.name = name;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public int getCount() {
    return count;
}

public void setCount(int count) {
    this.count = count;
}

public List<Node> getChildren() {
    return children;
}

public void setChildren(List<Node> children) {
    this.children = children;
}


public void addChild(Node n) {
    for (Node nn : children) {
        if (nn.name.equals(n.name)) {
            return;
        }
    }
    this.children.add(n);
}

public void addCost(int i) {
    this.count += i;
}
}

但我无法以正确的方式打印树。当它与孩子一样获得相同的节点时,它有时会产生无限循环。有人可以指导我吗?感谢。

1 个答案:

答案 0 :(得分:1)

我添加了生成Tree类结构的代码,使用了复合模式。

package com.test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class TestMain {

    public static void main(String[] args) {
        TestMain testMain = new TestMain();

        List<String> testData = new ArrayList<String>();
        testData.add("com-bo-news-2012,12");
        testData.add("com-bo-news-2015,3");
        testData.add("net-php-www,20");
        testData.add("net-phototrails,3");

        MyNode myNode = new MyNode("ROOT");

        for (String string : testData) {
            List<String> l = new ArrayList<String>();
            l.addAll(Arrays.asList(string.split("-")));

            testMain.buildTree(l, myNode);
        }

        printTree(myNode, 1);

    }

    private void buildTree(List<String> nodeNames, MyNode node) {
        if (nodeNames.isEmpty()) {
            return;
        }
        String nodeName = nodeNames.remove(0);
        MyNode myNode = new MyNode(nodeName);
        int index = node.getNodes().indexOf(myNode);

        if (index == -1) {
            node.getNodes().add(myNode);
        } else {
            myNode = node.getNodes().get(index);
        }

        buildTree(nodeNames, myNode);

    }

    private static void printTree(MyNode myNode, int tabCount) {
        for (int i = 0; i < tabCount; i++) {
            System.out.print("\t");
        }

        System.out.print(myNode.getNode() + "\n");

        for (int i = 0; i < tabCount; i++) {
            System.out.print("\t");
        }

        System.out.println("|");

        for (MyNode node : myNode.getNodes()) {
            printTree(node, ++tabCount);
        }

    }

}




package com.test;

import java.util.ArrayList;
import java.util.List;

public class MyNode {

    private String node;
    private List<MyNode> nodes;

    public MyNode(String node) {
        super();
        this.node = node;
        this.nodes = new ArrayList<MyNode>();
    }

    public MyNode(String node, List<MyNode> nodes) {
        super();
        this.node = node;
        this.nodes = nodes;
    }

    public String getNode() {
        return node;
    }

    public void setNode(String node) {
        this.node = node;
    }

    public List<MyNode> getNodes() {
        return nodes;
    }

    public void setNodes(List<MyNode> nodes) {
        this.nodes = nodes;
    }

    @Override
    public int hashCode() {
        return node.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass().equals(obj.getClass())) {
            return ((MyNode) obj).getNode().equals(node);
        }
        return false;

    }


    @Override
    public String toString() {
        return node + "[" + nodes.size()+"]";
    }

}

输出需要格式化一点,如果您有任何疑问,请告诉我