2011-07-19 12 views
5

は私がSet<Integer>[]取得パス

Set<Integer>[]として表さ木があります。

[ { 1 }, { 2, 3 }, { 4 }, { 5, 6, 7 } ] 

を以下のツリーを表しています。だから、

 1 
    /\ 
    / \ 
/ \ 
    2  3 
    |  | 
    4  4 
/|\  /|\ 
5 6 7 5 6 7 

ツリーの各レベルはSetとしてエンコードされます。ツリー内の特定のレベルの子供たちはすべて同じです。最初のセットには複数の整数が存在します。

私は、Set<Integer>[]から、根から葉へのすべてのパスのリストを取得したい:

[ [ 1, 2, 4, 5 ], [ 1, 2, 4, 6 ], [ 1, 2, 4, 7 ], [ 1, 3, 4, 5 ], [ 1, 3, 4, 6 ], [ 1, 3, 4, 7 ] ] 
+0

この場合、ツリーは一連の配列またはセットの配列として表されますか?私はちょっと混乱しています。 – Sam

+0

@Wesam:質問には: 'Set []'と書かれているので、 'Set 'の配列です。 – Jasper

答えて

4

木での検索のためのキーが通常実施しています特定のノードの隣接ノードを与える良いAjacency関数。

このツリーでは、隣接関係関数はノードがどのレベルにあるのかを見つけて、隣接ノードとして次のレベルのノードを返すことを望みます。

私たちは既にクラス内のフィールドとして定義されているツリーを持っていると仮定します。

検索を実行する前に、ルートを適切に設定し、パスにいくつかの事前作業をしたいと考えています。そこで私たちは、次の操作を行います。

/** 
* initializes our search, sets the root and adds it to the path 
*/ 
    public void initialize() { 
    root = -1; 
    for (Integer node : tree.get(0)) { 
     root = node; 
    } 
    currentPath.add(root); 
    } 

currentPathrootがすでにフィールドとして定義されていると仮定すると。

その後、私たちは木を横断する私たちの現在のパスに各ノードを追加し、ツリー上のDFS検索を実行し、私たちのセットパスにそのパスを追加し、我々はデッドエンド(葉)に達したときに、それをreseting:

/** 
    * runs a DFS on the tree to retrieve all paths 
    * @param tree 
    */ 
    public void runDFS(Integer node) { 
    if (getAdjacentsToNode(node) != null) { 
     for (Integer adjNode : getAdjacentsToNode(node)) { 
     currentPath.add(adjNode); 
     runDFS(adjNode); 
     } 
     currentPath.remove(currentPath.size() -1); 
    } else { 
     paths.add(currentPath.toArray(new Integer[0])); 
     currentPath.remove(currentPath.size() -1); 
    } 
    } 

クラス全体が、それゆえ、次のようになります。それをテストするには

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

public class DFS { 
    private List<Integer> currentPath = new ArrayList<Integer>(); 
    private List<Integer[]> paths = new ArrayList<Integer[]>(); 
    private ArrayList<Set<Integer>> tree; 
    private Integer root; 
    /** 
    * constructor 
    * @param tree 
    */ 
    public DFS(ArrayList<Set<Integer>> tree) { 
    this.tree = tree; 
    } 

    public List<Integer[]> getPaths() { 
    return paths; 
    } 
    public void setPaths(List<Integer[]> paths) { 
    this.paths = paths; 
    } 
    public Integer getRoot() { 
    return root; 
    } 
    public void setRoot(Integer root) { 
    this.root = root; 
    } 

/** 
* initializes our search, sets the root and adds it to the path 
*/ 
    public void initialize() { 
    root = -1; 
    for (Integer node : tree.get(0)) { 
     root = node; 
    } 
    currentPath.add(root); 
    } 

    /** 
    * This returns the adjacent nodes to an integer node in the tree 
    * @param node 
    * @return a set of adjacent nodes, and null otherwise 
    */ 
    public Set<Integer> getAdjacentsToNode(Integer node) { 

    for (int i = 0; i < tree.size(); i++) { 
     Set<Integer> level = tree.get(i); 
     if (level.contains(node) && i < tree.size() - 1) { 
     return tree.get(i + 1); 
     } 
    } 
    return null; 
    } 

    /** 
    * runs a DFS on the tree to retrieve all paths 
    * @param tree 
    */ 
    public void runDFS(Integer node) { 
    if (getAdjacentsToNode(node) != null) { 
     for (Integer adjNode : getAdjacentsToNode(node)) { 
     currentPath.add(adjNode); 
     runDFS(adjNode); 
     } 
     currentPath.remove(currentPath.size() -1); 
    } else { 
     paths.add(currentPath.toArray(new Integer[0])); 
     currentPath.remove(currentPath.size() -1); 
    } 
    } 
} 

、我々はこれを試してみてください。

public static void main(String[] args) { 
    ArrayList<Set<Integer>> tree = new ArrayList<Set<Integer>>(); 
    Set<Integer> level1 = new HashSet<Integer>(); 
    level1.add(new Integer(1)); 

    Set<Integer> level2 = new HashSet<Integer>(); 
    level2.add(new Integer(2)); 
    level2.add(new Integer(3)); 

    Set<Integer> level3 = new HashSet<Integer>(); 
    level3.add(new Integer(4)); 

    Set<Integer> level4 = new HashSet<Integer>(); 
    level4.add(new Integer(5)); 
    level4.add(new Integer(6)); 
    level4.add(new Integer(7)); 

    tree.add(level1); 
    tree.add(level2); 
    tree.add(level3); 
    tree.add(level4); 

    DFS dfsSearch = new DFS(tree); 
    dfsSearch.initialize(); 
    dfsSearch.runDFS(dfsSearch.getRoot()); 

    for (Integer[] path : dfsSearch.getPaths()) { 
     System.out.println(Arrays.toString(path)); 
    } 

となり、次のような出力が得られます。

[1, 2, 4, 5] 
[1, 2, 4, 6] 
[1, 2, 4, 7] 
[1, 3, 4, 5] 
[1, 3, 4, 6] 
[1, 3, 4, 7] 
0

私はコードを書くつもりはありませんが、最も簡単な方法は、第1の深さになります各レベルで現在のパスに各エントリを追加します。

また、戻り値はリストのコレクション(または配列)になります(垂直パスは順序付けられていないセットなので)。擬似コードで

def getPaths(levels) { 
    return getPaths(levels, 0, new Set()) 
} 

def getPaths(levels, currentIndex, paths) { 

    if(currentIndex == levels.length) 
    return paths 

    def newPaths = new Set(paths) 

    for(path : paths) { 
    for(level : levels) { 
     newPaths.add(path + level) 
    } 
    } 

    return getPaths(levels, currentIndex + 1, newPaths) 

} 
0

はこのような何かを試してみてください:

public static List<Integer[]> getAllPaths(Set<Integer>[] tree){ 

    // Get the overall number of path 
    int totalSize = 1; 
    for(Set<Integer> line : tree){ 
     totalSize *= line.size(); 
    } 

    // Create the empty paths 
    List<Integer[]> allPaths = new ArrayList<Integer[]>(totalSize); 
    for(int i = 0 ; i<totalSize ; ++i){ 
     Integer[] path = new Integer[tree.length]; 
     allPaths.add(path); 
    } 

    // Fill the paths 
    int indexLine = 0; 
    for (Set<Integer> line : tree) { 
     Iterator<Integer[]> pathIterator = allPaths.iterator(); 
     Iterator<Integer> lineIterator = line.iterator(); 
     while(pathIterator.hasNext()){ 
      if(!lineIterator.hasNext()){ 
       lineIterator = line.iterator(); 
      } 
      pathIterator.next()[indexLine] = lineIterator.next(); 
     } 
     ++indexLine; 
    } 
    return allPaths; 
} 

それはあなたの例のために働く:

public static void main(String[] args) { 

    Set<Integer> line1 = new HashSet<Integer>(); 
    line1.add(new Integer(1)); 
    Set<Integer> line2 = new HashSet<Integer>(); 
    line2.add(new Integer(2)); 
    line2.add(new Integer(3)); 
    Set<Integer> line3 = new HashSet<Integer>(); 
    line3.add(new Integer(4)); 
    Set<Integer> line4 = new HashSet<Integer>(); 
    line4.add(new Integer(5)); 
    line4.add(new Integer(6)); 
    line4.add(new Integer(7)); 

    Set[] test = {line1, line2,line3,line4}; 

    List<Integer[]> allPaths = getAllPaths(test); 

    for(Integer[] path : allPaths){ 
     System.out.println(Arrays.toString(path)); 
    } 
} 
関連する問題