2016-05-04 21 views
0

を使用して、ツリーのようなクラスの子を取得:私は次のようにクラスクラスタを構築し、再帰

public class Cluster 
{ 
    List<Cluster> lstChildClusters=new List<Cluster>(); 

    public List<Cluster> LstChildClusters 
    {  
     get { return lstChildClusters; } 
     set { lstChildClusters = value; } 
    } 

    public classA alr; 
} 

私の目標は、0を持つことができますtype.Basicallyクラスタのオブジェクトのすべての孫の父親を取得する機能を構築することですまたは0人以上の息子を持つことができるより多くの息子。

再帰関数を作成しようとしましたが、戻ってくるのは、下のコードを使用している孫だけです。 ここで私が構築された機能である:

public List<classA> getLevel0Clusters(Cluster cluster,List<classA> list) 
    { 
     if (cluster.LstChildClusters.Count == 0) 
     { 
      list.Add(cluster.alr); 
      return (list); 

     } 
     else 
     { 
      for (int i = 0; i < lstChildClusters.Count - 1; i++) 
      { 
       return (lstChildClusters[i].getLevel0Clusters(lstChildClusters[i], list)); 
      } 
      return (lstChildClusters[0].getLevel0Clusters(lstChildClusters[0], list)); 
     } 

    } 

私はデバッグのためにそれらのインスタンスを使用していますが:

Cluster father = new Cluster(); 
     father.Alr = new Alarm("father"); 
     Cluster son1 = new Cluster(); 
     son1.Alr = new Alarm("son1"); 
     Cluster son2 = new Cluster(); 
     son2.Alr = new Alarm("son2"); 
     Cluster grandson1 = new Cluster(); 
     grandson1.Alr = new Alarm("grandson1"); 
     Cluster grandson2 = new Cluster(); 
     grandson2.Alr = new Alarm("grandson2"); 
     father.LstChildClusters.Add(son1); 
     father.LstChildClusters.Add(son2); 
     son1.LstChildClusters.Add(grandson1); 
     son1.LstChildClusters.Add(grandson2); 
List<classA> lst=new lst<ClassA>(); 
lst=father.getLevel0Clusters(father, father.LstAlarms); 

は、誰もがこの問題を解決する方法上の任意の手掛かりを持っていますか? ありがとうございました

+0

は、私はあなたのクラスDEFSとサンプルデータを提供することを最初に感動しましたが、私は行ったときそれらをテストするために、それらはコンパイルされません。あなたのコードをテストしたなら、本当に役に立ちます。 – Enigmativity

答えて

2

多くの問題があります。あなたの存在と一緒にコードを作成したので、プログラムを簡単にするためにリファクタリングを少ししました。

まず、あなたの直接の質問に答えるために、既存の方法の問題は、すべての結果を集約する前にreturnと呼んでいることです。あなたのコードはgrandfatherを見て、子があることを確認してforループに入り、再帰的にそれ自身をson1と呼んでいます。 son1には子があるので、forループに入り、子を持たないgrandson1を再帰的に呼び出すので、リストにgrandson1を追加して戻ります。外側の呼び出しは最初の値を見つけた後に戻り、次の2つのレベルがちょうど戻ってきます。従ってリストにはgrandson1しかありません。だから、

は、あなたのコードをリファクタリングします(それはそれは thisを使用することができます Clusterクラスで定義されている)と getLevel0Clusters方法は Clusterに渡す必要はありません List<classA>(それは必要に応じて1を生成することができます)。

だからあなたgetLevel0Clustersは、単純にこのなることができます:私はあなたのサンプルコードは、このように修正コンパイルするすべてのものを得るためには

public List<classA> getLevel0Clusters() 
{ 
    return new[] { this.alr, } 
     .Concat(this.LstChildClusters 
      .SelectMany(child => child.getLevel0Clusters())) 
     .ToList(); 
} 

Cluster father = new Cluster(); 
father.alr = new classA("father"); 
Cluster son1 = new Cluster(); 
son1.alr = new classA("son1"); 
Cluster son2 = new Cluster(); 
son2.alr = new classA("son2"); 
Cluster grandson1 = new Cluster(); 
grandson1.alr = new classA("grandson1"); 
Cluster grandson2 = new Cluster(); 
grandson2.alr = new classA("grandson2"); 
father.LstChildClusters.Add(son1); 
father.LstChildClusters.Add(son2); 
son1.LstChildClusters.Add(grandson1); 
son1.LstChildClusters.Add(grandson2); 
List<classA> lst = father.getLevel0Clusters(); 

を...このように、あなたのクラス:

public class Cluster 
{ 
    List<Cluster> lstChildClusters = new List<Cluster>(); 

    public List<Cluster> LstChildClusters 
    { 
     get { return lstChildClusters; } 
     set { lstChildClusters = value; } 
    } 
    public classA alr; 

    public List<classA> getLevel0Clusters() 
    { 
     return new[] { this.alr, } 
      .Concat(this.LstChildClusters 
       .SelectMany(child => child.getLevel0Clusters())) 
      .ToList(); 
    } 
} 

public class classA 
{ 
    public string Name; 
    public classA(string name) 
    { 
     this.Name = name; 
    } 
} 

私はあなたのサンプルコードを実行したとき、私はこの結果を得た:

result

1

子孫を見つけるとすぐに、呼び出し元のプログラムに戻ります。 カウントの値が正対以外には効果がありません:あなたは、ループを入力し、lstChildClustersを呼び出す[0] .getLevel0Clusters(lstChildClusters [0]、およびをインクリメントし、継続して悩ませずにその値を返しますループが。

代わりに、あなたのためのループがリストに各戻り値を追加する必要があります。ループが行われた後、あなたが呼び出しプログラムに戻ることができます。

関連する問題