2016-12-19 8 views
0

私は、友人を表すクラスと親友のペアと親友のペアのリストを表すクラスを持ち、それぞれの親友に間接的に関連する各友人を知りたいと思っています。次のように:関連クラスのリストを再帰的に検索する

class Friend 
{ 
    string Name; 
} 

class BestFriends 
{ 
    Friend NameFriend1; 
    Friend NameFriend2; 
} 

List<BestFriends> ListOfBestFriends = new List<BestFriends>(); 

Suposeを次のように私はBestFriendsのペアを持っている:

  • アダムとブライアン。
  • ブライアンとクリス;
  • ChrisとDaniel;
  • Eddie and Ian;
  • ブライアンとジョン。

特定の友人に間接的に関連するすべての友人のリストを返すメソッドを作成したいと思います。例えば、私がブライアンの間接的な友人をすべて欲しければ、このメソッドは{Adam、Chris、Daniel、John}を返します。

List<Friend> IndirectFriends (Friend friendToHasItsIndirectFriendsFound, List<BestFriends> bestFriendsPairs) 
{ 
    ... 
} 

どうすればいいですか?

+0

以下IComparableインターフェイスのリンクを実装する必要があります。関連クラスを検索するのではなく、同じクラスの関連オブジェクト(あなたの場合は「Friend」です)を検索しています。これを考えると、私はあなたの 'IndirectFriends'メソッドで最初のパラメータの意味を理解していません。あなたが間接的な友達をしたいと思っているのは「Friend」だと思いますか? "IndirectFriend"はどのように定義しますか?あなたの再帰の深さ、または間接を見つけるために友人の親友から始まる最初のレベルだけ?どうか明らかにしてください。 ヒント:グラフを読み上げます。 –

+1

私はスタックオーバーフローの答えの範囲を超えているかもしれないグラフトラバーサルアルゴリズムが効果的だと思います。 – BradleyDotNET

+0

@ K.Berger 'Friend'パラメータは、すべての間接的に関連する友人を見つけたい友達です。 「間接的な友人」とは、すべてのレベルのすべての友人が、「友人」パラメータに黙って接続できることを意味します(私の例を見てください)。私はグラフの横断を使用すべきだと思いますが、以前はそれを使ったことがありません。 –

答えて

0
BestFriends.Where(
    b=>b.NameFriend1.Name!=friend.Name && 
    b.NameFriend2.Name!=friend.Name && 
    BestFriends.Any(b2=>b2.NameFriend1.Name==friend.Name||b2.NameFriend2.Name==friend.Name)); 

また友達クラスにIDを追加することを検討し、代わりに名前

+0

これは1つのレベルの深さに過ぎません。彼がもっと欲しいのであれば、本当のグラフトラバーサルが必要です。 – BradleyDotNET

1

の比較するために、それを使用するには、グラフトラバーサルを検索します。あなたのケースでは、このような友人クラスに親友のリストを追加することができます。

class Friend 
{ 
    string Name; 
    List<Friend> bestFriends; 
} 

その後、あなたが持っているBestFriendsペアを使用して、各友人のために、このリストを埋めます。

その後、幅優先や深さ優先検索を使用して、すべての間接的に関連する友人を見つけることができます。

+0

はい、私はグラフ横断を使用しなければならないと思います。ありがとう! 他の理由で私の友人のクラスに親友のリストを追加することはできません。 –

+0

クラスを変更できない場合は、代わりに友人のベストフレンドのリストを保持する辞書を作成することができます: 'Dictionary >' – fafl

1

これを解決するために、セットベースの操作を使用することを検討してください。

提案したデータ構造が与えられているので、問題を解決するために、直接の友人と間接的な友人の両方で解決する必要があります。直接の友人の場合は2件あります。 1、共通の友人はNameFriend1、もう1人はnameFriend2です。これらの2つのケースは、メソッドIndirectFriendsの終わりに解決されます。

直接の友人の結果を2番目のリストのNameFriend1に、2番目のリストのNameFriend2のときにもう1つ、同じ友人の結果を同じデータセットに2回参加させる必要があるため、 。そのため、解決すべき4つのケースがあります。

IndirectFriendsメソッドの最後に、共通の友だちをリストから除外し、別個の結果のみを返します。

このコードは、同じオブジェクトbrianがリスト内で使用されているため、また比較のためにのみ使用されます。あなたが同じ値を持つ新しい変数をインスタンス化していて、それらが等しいものとしてLINQによって評価されるようにしたい場合は、あなたの文言が誤解を招く How to Implement IComparable interface?

[TestMethod] 
public void TestMethod1() 
{ 
    List<BestFriends> ListOfBestFriends = new List<BestFriends>(); 
    var adam = new Friend { Name = "Adam" }; 
    var brian = new Friend { Name = "Brian" }; 
    var chris = new Friend { Name = "Chris" }; 
    var daniel = new Friend { Name = "Daniel" }; 
    var eddie = new Friend { Name = "Eddie" }; 
    var ian = new Friend { Name = "Ian" }; 
    var john = new Friend { Name = "John" }; 

    ListOfBestFriends.Add(new BestFriends { NameFriend1 = adam, NameFriend2 = brian }); 
    ListOfBestFriends.Add(new BestFriends { NameFriend1 = brian, NameFriend2 = chris }); 
    ListOfBestFriends.Add(new BestFriends { NameFriend1 = chris, NameFriend2 = daniel }); 
    ListOfBestFriends.Add(new BestFriends { NameFriend1 = eddie, NameFriend2 = ian }); 
    ListOfBestFriends.Add(new BestFriends { NameFriend1 = brian, NameFriend2 = john }); 

    var result = IndirectFriends(brian, ListOfBestFriends); 
} 

List<Friend> IndirectFriends(Friend commonFriend, List<BestFriends> bestFriendsPairs) 
{ 
    /* Get inDirect Friends where commonfriend = NameFriend2 */ 
    /* First list is joined on Namefriend2 and Namefriend1 */ 
    var l1 = (from bfp in bestFriendsPairs 
       join bfpR in bestFriendsPairs 
       on bfp.NameFriend2 equals bfpR.NameFriend1 
       where bfp.NameFriend1 == commonFriend 
       select bfpR.NameFriend2).ToList(); 

    /* Get inDirect Friends where commonfriend= NameFriend2 */ 
    /* First list is joined on Namefriend2 and Namefriend2 */ 
    l1.AddRange(from bfp in bestFriendsPairs 
     join bfpR in bestFriendsPairs 
      on bfp.NameFriend2 equals bfpR.NameFriend2 
     where bfp.NameFriend1 == commonFriend 
     select bfpR.NameFriend1); 

    /* Get InDirect Friends where commonfriend = NameFriend2 */ 
    /* First list is joined on Namefriend1 and Namefriend2 */ 
    l1.AddRange (from bfp in bestFriendsPairs 
       join bfpL in bestFriendsPairs 
       on bfp.NameFriend1 equals bfpL.NameFriend2 
       where bfp.NameFriend2 == commonFriend 
       select bfpL.NameFriend1); 

    /* Get InDirect Friends where commonfriend= NameFriend2 */ 
    /* First list is joined on Namefriend1 and Namefriend1 */ 
    l1.AddRange(from bfp in bestFriendsPairs 
       join bfpL in bestFriendsPairs 
       on bfp.NameFriend1 equals bfpL.NameFriend1 
       where bfp.NameFriend2 == commonFriend 
       select bfpL.NameFriend2); 

    /* Get Direct Friends where commonfriend= NameFriend2 */ 
    l1.AddRange(from bfp in bestFriendsPairs 
       where bfp.NameFriend2 == commonFriend 
       select bfp.NameFriend1); 

    /* Get Direct Friends where commonfriend= NameFriend1 */ 
    l1.AddRange(from bfp in bestFriendsPairs 
       where bfp.NameFriend1 == commonFriend 
       select bfp.NameFriend2); 

    /*exclude commonfriend, and get distinct */ 
    return l1.Where(f=>f!= commonFriend).Distinct().ToList(); 
} 
関連する問題