2015-09-09 36 views
-1

我有一個列表中的簡單的播放器對象,如下獲得所有可能的組合和和結果

 
Name   | Team | Position | Total 
Tom Brady  | Team 1 | QB  | 200 
Adrian Peterson | Team 1 | RB  | 250 
Calvin Johnson | Team 2 | WR  | 260 
LeVon Bell  | Team 2 | RB  | 220 
Peyton Manning | Team 3 | QB  | 220 
Arian Foster | Team 3 | RB  | 220 

這是一個簡單的示例,在現實中有大約200條記錄。我想要做的是讓每個隊員所有可能的組合,總結他們的總,所以最終的產品將是如下

可能性

 
Teams | Players       | Total 
Team 1 | Tom Brady, Adrian Peterson  | 450 
Team 2 | Calvin Johnson, LeVon Bell  | 480 
Team 3 | Peyton Manning, Arian Foster | 440 

基本上我尋找貿易機會,所以我需要得到每支球隊的球員組合。我期待的最大可能的組合是每個球隊5名球員,我將球員和他們的積分組合成一個新對象。現在我可以用下面的方式到達那裏。

var playerList = players.GroupBy(p => p.Team) 
    .Select(g => new 
    { 
     Team = g.Key, 
     g 
    }).ToList(); 

     List<Possibilities> possibilities = new List<Possibilities>(); 

     foreach (var a in playerList) 
     { 
      List<Possibilities> onePlayer = (from b in a.g 
              select new Possibilities 
              { 
               Players = b.Name, 
               Total = b.Total, 
               Team = a.Team 
              }).ToList(); 


      List<Possibilities> twoPlayer = (from b in a.g 
              from c in a.g 
              select new Possibilities 
              { 
               Players = b.Name + ", " + c.Name, 
               Total = b.Total + c.Total, 
               Team = a.Team 
              }).ToList(); 

這讓我的每隊球員1,2,3所有的組合,但我想補充4和5這也不會刪除重複的組合(玩家1,玩家2和玩家2,PLAYER1 )。有沒有更乾淨的方法來做到這一點?

+1

看起來你只是想在「Team」上進行分組,但你到底意味着什麼?每個團隊最多有20個玩家,每個組合最多可以組合5個玩家,所以我希望每個團隊有15.5k個可能。如果你想要所有人你的榜樣不應該包含每個球隊只有一名球員的可能性嗎? – juharr

+0

問題有點不清楚。我會嘗試重新編寫它,或者發佈您迄今爲止編寫的代碼。 – jackncoke

+0

基本上我在尋找交易的可能性,所以我需要得到每支球隊的球員組合。我期待的最大可能的組合是每個球隊5名球員,我將球員和他們的積分組合成一個新對象。那有意義嗎? –

回答

0

雖然效率可能很低,但下面的方法可能會奏效。當然,這只是一個簡單的例子,您需要根據自己的情況調整代碼。

static void Main(string[] args) 
    { 
     var nums = new[] { 1, 2, 3, 4, 5, 6 }; 
     var combinations = new List<int[]>(); 
     int[] current; 

     foreach (int i in nums) 
     { 
      combinations.Add(new[] { i }); 

      foreach (int j in nums.Where(n => n != i)) 
      { 
       current = new[] { i, j }; 
       if (!combinations.Any(c => current.Length == c.Length && current.All(n => c.Contains(n)))) 
       { 
        combinations.Add(current); 
       } 

       foreach (int k in nums.Where(n => n != i && n != j)) 
       { 
        current = new[] { i, j, k }; 
        if (!combinations.Any(c => current.Length == c.Length && current.All(n => c.Contains(n)))) 
        { 
         combinations.Add(current); 
        } 

        foreach (int l in nums.Where(n => n != i && n != j && n != k)) 
        { 
         current = new[] { i, j, k, l }; 
         if (!combinations.Any(c => current.Length == c.Length && current.All(n => c.Contains(n)))) 
         { 
          combinations.Add(current); 
         } 

         foreach (int m in nums.Where(n => n != i && n != j && n != k && n != l)) 
         { 
          current = new[] { i, j, k, l, m }; 
          if (!combinations.Any(c => current.Length == c.Length && current.All(n => c.Contains(n)))) 
          { 
           combinations.Add(current); 
          } 
         } 
        } 
       } 
      } 
     } 

     foreach (var c in combinations) 
     { 
      foreach (var num in c) 
      { 
       Console.Write(num + " "); 
      } 

      Console.WriteLine(); 
     } 

     Console.ReadKey(); 
    } 
1

可以生成一組有限的項的所有組合(其中的項目數是< = 31),通過使用一個二進制數計數。二進制數中的每一位表示組合中存在的項目。

例如,計數(二進制)爲一組的3個項目:在該二進制數

000, 001, 010, 011, 100, 101, 110, 111 

A 1表示在該組中的相應的項目應該包括在那個組合。

如果要確保組合包含某個範圍內的項目數,則需要對在二進制數中設置的位進行計數,並檢查該數是否在範圍內。有一種有效的方式可以使用位混合(see here for examples)。

把它放在一起給出如下代碼。運行它並檢查輸出。希望你能看到如何在你的程序中使用它。

該示例產生取自項目2和3之間的所有組合A,B,C,D,其輸出是:

A,B 
A,C 
B,C 
A,B,C 
A,D 
B,D 
A,B,D 
C,D 
A,C,D 
B,C,D 

的代碼是:

using System; 
using System.Collections.Generic; 

namespace ConsoleApplication1 
{ 
    public class Program 
    { 
     public static void Main() 
     { 
      var data = new [] {"A", "B", "C", "D"}; 

      // Get all the combinations of elements from A,B,C,D with between 2 and 3 values: 

      var combinations = Combinations(data, 2, 3); 

      // Combinations() has returned an IEnumerable<IEnumberable<T>>, 
      // that is, a sequence of subsequences where each subsequence is one combination. 

      foreach (var combination in combinations) 
       Console.WriteLine(string.Join(",", combination)); 
     } 

     public static IEnumerable<IEnumerable<T>> Combinations<T>(T[] input, int minElements, int maxElements) 
     { 
      int numCombinations = 2 << (input.Length - 1); 

      for (int bits = 0; bits < numCombinations; ++bits) 
      { 
       int bitCount = NumBitsSet(bits); 

       if (minElements <= bitCount && bitCount <= maxElements) 
        yield return combination(input, bits); 
      } 
     } 

     private static IEnumerable<T> combination<T>(T[] input, int bits) 
     { 
      for (int bit = 1, i = 0; i < input.Length; ++i, bit <<= 1) 
       if ((bits & bit) != 0) 
        yield return input[i]; 
     } 

     public static int NumBitsSet(int i) 
     { 
      i = i - ((i >> 1) & 0x55555555); 
      i = (i & 0x33333333) + ((i >> 2) & 0x33333333); 
      return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24; 
     } 
    } 
} 
+0

感謝你們,我會看看它,因爲我不僅需要組合,還需要在此期間計算字段,這可能需要多一點思考。 –

相關問題