在Java

时间:2015-06-01 08:13:36

标签: java data-structures tree

由于某种原因,我在这上面写了一个空白,也许我的大脑最近超负荷,但我似乎无法做到正确。我正在尝试将结构化的唯一值列表转换为树结构。

我有一个在Apache MultiKey类中设置的唯一值列表,它基本上只是构成键的任意数量对象的包装器。他们的列表看起来像这样:

List<MultiKey> _data = new ArrayList<MultiKey>()

内部数据如下所示:

MultiKey[ABC]
MultiKey[ABC, 111]
MultiKey[ABC, 111, CHF]
MultiKey[ABC, 111, CHF, AT000B049432]
MultiKey[ABC, 111, CHF, CH0012814965]
MultiKey[ABC, 111, CHF, CH0018550399]
MultiKey[ABC, 111, CHF, CH0020626773]
MultiKey[ABC, 111, EUR]
MultiKey[ABC, 111, EUR, AT0000A001X2]
MultiKey[ABC, 111, EUR, AT0000A0U3T4]
MultiKey[ABC, 111, USD]
MultiKey[ABC, 111, USD, CH0002497458]
MultiKey[DEF]
MultiKey[DEF, 222]
MultiKey[DEF, 222, CHF]
MultiKey[DEF, 222, CHF, AT000B049432]
MultiKey[DEF, 222, CHF, CH0012814965]
MultiKey[DEF, 222, EUR]
MultiKey[DEF, 222, EUR, AT0000A001X2]

构成树节点的类是一个经典的父子树节点,看起来像这样(为简单起见,排除了其他方法)。

public class DataTreeNode {

    private Object              _data;
    private DataTreeNode        _parent;
    private List<DataTreeNode>  _children;

    public DataTreeNode() {
        super();
    }

    public DataTreeNode(Object data) {
        super();
        _data = data;
    }

    public DataTreeNode getParent() {
        return _parent;
    }

    public void setParent(DataTreeNode parent) {
        _parent = parent;
    }

    public Object getData() {
        return _data;
    }

    public void addChild(DataTreeNode child) {
        if (!_children.contains(child)) {
            _children.add(child);
            child.setParent(this);
        }
    }

    public List<DataTreeNode> getChildren() {
        return _children;
    }

}

我们的想法是遍历键和(使用示例数据)来构建这样的树:

ABC
  111
    CHF
      AT000B049432
      CH0012814965
      CH0018550399
      CH0020626773
    EUR
      AT0000A001X2
      AT0000A0U3T4
    USD
      CH0002497458
DEF
  222
    CHF
      AT000B049432
      CH0012814965
    EUR
      AT0000A001X2

这是一个完全可运行的Java示例,它使用MultiKey结构构建示例数据,但缺少convert-to-tree实现。

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

import org.apache.commons.collections.keyvalue.MultiKey;

public class Sample {

    public static void main(String [] args) { 
        List<MultiKey> data = new ArrayList<MultiKey>();

        data.add(new MultiKey(new Object [] { "ABC" }));
        data.add(new MultiKey(new Object [] { "ABC", "111" }));
        data.add(new MultiKey(new Object [] { "ABC", "111", "CHF" }));
        data.add(new MultiKey(new Object [] { "ABC", "111", "CHF", "AT000B049432" }));
        data.add(new MultiKey(new Object [] { "ABC", "111", "CHF", "CH0012814965" }));
        data.add(new MultiKey(new Object [] { "ABC", "111", "CHF", "CH0018550399" }));
        data.add(new MultiKey(new Object [] { "ABC", "111", "CHF", "CH0020626773" }));
        data.add(new MultiKey(new Object [] { "ABC", "111", "EUR" }));
        data.add(new MultiKey(new Object [] { "ABC", "111", "EUR", "AT0000A001X2" }));
        data.add(new MultiKey(new Object [] { "ABC", "111", "EUR", "AT0000A0U3T4" }));
        data.add(new MultiKey(new Object [] { "ABC", "111", "USD" }));
        data.add(new MultiKey(new Object [] { "ABC", "111", "USD", "AT0000A0U3T4" }));
        data.add(new MultiKey(new Object [] { "DEF" }));
        data.add(new MultiKey(new Object [] { "DEF", "222" }));
        data.add(new MultiKey(new Object [] { "DEF", "222", "CHF" }));
        data.add(new MultiKey(new Object [] { "DEF", "222", "CHF", "AT000B049432" }));
        data.add(new MultiKey(new Object [] { "DEF", "222", "CHF", "CH0012814965" }));
        data.add(new MultiKey(new Object [] { "DEF", "222", "EUR" }));
        data.add(new MultiKey(new Object [] { "DEF", "222", "EUR", "AT0000A001X2" }));

        DataTreeNode treeFromData = Sample.getTreeFor(data);
        // ...
    }

    public static DataTreeNode getTreeFor(List<MultiKey> data) {
        // TODO: THIS!
        return null;
    }
}

提前感谢您解决此问题的任何帮助!

2 个答案:

答案 0 :(得分:0)

如果不是家庭作业,您可以自由使用任何简化操作的数据结构。

我建议使用地图来映射,例如&#34; ABC&#34;到代表它的节点。这将使您的树更容易构建。

答案 1 :(得分:0)

感谢大家的评论,最后我的大脑终于点击了。我同意MultiKey不是理想的结构,但基本上它起到了作用。

我在DataTreeNode类中添加了以下方法:

public void printTree() {
    printTree(0);
}

private void printTree(int i) {
    for (int x = 0; x < i; x++) {
        System.out.print(" ");
    }
    System.out.println(this);
    for (DataTreeNode child : _children) {
        child.printTree(i+1);
    }
}

public void buildFrom(DataTreeNode root, MultiKey mk) {
    buildFrom(root, 0, mk);
}

private void buildFrom(DataTreeNode root, int start, MultiKey mk) {
    if (start >= mk.getKeys().length) {
        return;
    }
    // get value
    Object val = mk.getKey(start);
    // value exists?
    DataTreeNode tn = root.getChildWithValue(val);
    if (tn == null) {
        tn = new DataTreeNode(val);
        root.addChild(tn);
    }
    else {
        buildFrom(tn, ++start, mk);
    }       
}

private DataTreeNode getChildWithValue(Object o) {
    for (DataTreeNode tn : _children) {
        if (tn.getData() == o) {
            return tn;
        }
    }
    return null;
}

@Override
public String toString() {
    return "[DataTreeNode: " + _data + "]";
}

getTreeFor方法变为:

public static DataTreeNode getTreeFor(List data){     DataTreeNode root = new DataTreeNode();

for (MultiKey mk : data) {
    DataTreeNode node = new DataTreeNode();
    node.buildFrom(root, mk);           
}

return root;

}

因此终于

treeFromData.printTree();

打印出来

[DataTreeNode: null]
 [DataTreeNode: ABC]
  [DataTreeNode: 111]
   [DataTreeNode: CHF]
    [DataTreeNode: AT000B049432]
    [DataTreeNode: CH0012814965]
    [DataTreeNode: CH0018550399]
    [DataTreeNode: CH0020626773]
   [DataTreeNode: EUR]
    [DataTreeNode: AT0000A001X2]
    [DataTreeNode: AT0000A0U3T4]
   [DataTreeNode: USD]
    [DataTreeNode: AT0000A0U3T4]
 [DataTreeNode: DEF]
  [DataTreeNode: 222]
   [DataTreeNode: CHF]
    [DataTreeNode: AT000B049432]
    [DataTreeNode: CH0012814965]
   [DataTreeNode: EUR]
    [DataTreeNode: AT0000A001X2]

除了清理代码外,还可以。

再次感谢!