0

Map<List<String>,Integer>各エントリがパス(List<String>)とカウントである場所があります

元:

["a1", "a2", "a3"] => 4
["a1", "a2"] => 2
["b1", "b2", "b3"] => 3
["b1"] => 4
["b1", "b2"] => 3
["c1", "c2", "c3", "c4"] => 5

各ノードのカウントを含むツリーを出力したい

木:

- ROOT
-- a1 : 6
--- a2 : 6
---- a3 : 4
-- b1 : 7
--- b2 : 3
-- c1 : 5
--- c2 : 5
---- c3 : 5
----- c4 : 5

JSON構造:

{
    "name": "",
    "count": "",
    "children": [
        {
            "name": "",
            "count": "",
            "children": []
        }
    ]
}

最も効率的なデータ構造と、この場合の使用方法(ツリーをJSONツリーにシリアル化する必要があります)は何でしょうか?

4

3 に答える 3

2

ノードを使用してツリー構造を作成し、XStreamを使用して構造をシリアル化します。以下の例で、これがお役に立てば幸いです。

ノード構造への変換

public static Node createNodes(Map<List<String>, Integer> map) {
    Map<String, Node> namemap = new HashMap<String, Node>();
    Node root = new Node();
    Node current;
    for (Entry<List<String>, Integer> path : map.entrySet()) {
        current = root;
        for (String nodename : path.getKey()) {
            Node p;
            if (!namemap.containsKey(nodename)){
                p = new Node(nodename, path.getValue());
                namemap.put(nodename, p);
            }else {
                p = namemap.get(nodename);
                p.addCost(path.getValue());
            }
            current.addChild(p);
            current = p;
        }

    }

    return root;
}

シリアル化

public static String toXML(Node n) {
    XStream xstream = new XStream(new JsonHierarchicalStreamDriver());
    xstream.alias("node", Node.class);
    return xstream.toXML(n);
}

ノードオブジェクト

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

JSON出力

{"node": {
  "count": 0,
  "children": [
    {
      "name": "c1",
      "count": 5,
      "children": [
        {
          "name": "c2",
          "count": 5,
          "children": [
            {
              "name": "c3",
              "count": 5,
              "children": [
                {
                  "name": "c4",
                  "count": 5,
                  "children": [
                  ]
                }
              ]
            }
          ]
        }
      ]
    },
    {
      "name": "b1",
      "count": 10,
      "children": [
        {
          "name": "b2",
          "count": 6,
          "children": [
            {
              "name": "b3",
              "count": 3,
              "children": [
              ]
            }
          ]
        }
      ]
    },
    {
      "name": "a1",
      "count": 6,
      "children": [
        {
          "name": "a2",
          "count": 6,
          "children": [
            {
              "name": "a3",
              "count": 4,
              "children": [
              ]
            }
          ]
        }
      ]
    }
  ]
}}
于 2013-01-11T14:41:09.377 に答える
0

私は個人的に、子とカウント値を持つNodeクラスを作成し、JSONシリアライザーにニーズに合わせて適切にシリアル化する方法を指示します。

于 2013-01-11T13:43:27.297 に答える
0

マップを次のように変更します。

Map<String[], Integer>

リストを使い続けたい場合は、それを使用ArrayListしてtrim()。

次に、を使用するHashMapか、本当にツリーが必要か(TreeMap)を決定する必要があります。後者の場合、フィールドString[]または。を使用してPathオブジェクトを作成する必要がありますList<String>
次に、このPathオブジェクトは、実装する必要Comparableがあります。

(Jsonまたは他のシステム)を実行するSerialisationには、通常、キーと値のペアを書き出します。もう一度読み返すと、(キー、値)のペアを入力して、マップまたはツリーを再度構築します。

jsonまたはその他のシリアル化されたファイルにツリー構造を含めることはお勧めできません。あなたはそれをほとんど必要としないでしょう。

于 2013-01-11T14:02:50.153 に答える