2016-07-21 9 views
1

Derzeit habe ich dieses Code-Snippet, das tut was ich will: gegeben einige Objekte, es schafft alle möglichen Kombinationen zwischen ihnen.Wie wird aus einem kombinatorischen hartcodierten Snippet eine rekursive Funktion?

In diesem Beispiel werden bei der Darstellung von 4 Objekten (0, 1, 2 und 3) alle möglichen Kombinationen der 4 Objekte erstellt (0, 1, 2, 3, 01 (die Kombination von 0 und 1)), 02, 03, 12, 13, 23, 012, 013, 023, 123 und 0123).

Zu beachten ist, dass es 2^4 - 1 = 15 Kombinationen und generell 2^Anzahl der Objekte - 1 Kombinationen gibt.

Die Reihenfolge der angelegten Objekte mit diesem Code lautet: 0 -> 01 -> 012 ->-> 013 -> 02 -> 023 -> 03 -> 1 -> 12 -> 123 -> 13 - > 2 -> 23 -> 3

Die Art, wie ich die ursprünglichen Objekte und deren Anzahl erhalte, wird an anderer Stelle im Code definiert.

int count = 4; //this is gotten elsewhere 
int currPos = 0; 
var objects = new Object[(2^count)-1]; 

for (int i = 0; i < count; i++) //loop that creates combinations of only one object 
{ 
    Object obj = new Object(...); 
    objects[currPos] = obj; 
    currPos += 1; 

    for (int j = i + 1; j < count; j++) //loop that creates combinations of two objects 
    { 
     Object obj = new Object(...); 
     objects[currPos] = obj; 
     currPos += 1; 

     for (int k = j + 1; k < count; k++) //loop that creates combinations of three objects 
     { 
      Object obj = new Object(...); 
      objects[currPos] = obj; 
      currPos += 1; 

      for (int l = k + 1; l < count; l++) //loop that creates combinations of four objects 
      { 
       Object obj = new Object(...); 
       objects[currPos] = obj; 
       currPos += 1; 
      } 
     } 
    } 
} 

Trotz der richtigen Ergebnisse zu geben, wird diese hart codierte und somit für eine Art und Weise in eine rekursive Funktion, die ich bin auf der Suche zu ändern (aber konserviert, seine Funktionalität), mit der Anzahl der Objekte (die auch das Maximum bestimmt Kombinationen, vier im Beispiel) als Parameter übergeben.

Ich habe versucht, unter so etwas wie den Code zu tun, aber ohne Ergebnis, vor allem, weil ich nicht auf die „Zurück“ Schleife zu gehen scheinen notwendig, wenn, beispielsweise vonbis 013. gehen

int count = 4; 
    int currPos = 0; 
    var objects = new Object[(2^count)-1]; 
    combinations(count, 0, currPos, objects); //called elsewhere 

    private void combinations(int numberOfObjects, int j, int count, int currPos, Object[] objects) 

    { 
     if (numberOfObjects == count) 
     { 
      for (int k = j; k < count; k++) 
      { 
       Object obj = new Object(...); 
       objects[currPos] = obj; 
       currPos += 1; 
       generateCombinations(numberOfObjects - 1, j + 1, count, currPos, objects); 
      } 
     } 

     if (numberOfObjects < count) 
     { 
      for (int l = j; l < count; l++) 
      { 
       Object obj = new Object(...); 
       objects[currPos] = obj; 
       currPos += 1; 

       (...) 

       generateCombinations(..., ..., count, currPos, objects); 
      } 
     } 
    } 
+0

Verwunderlich, dass [Suche] (https://www.bing.com/search ? q = c% 23% 20all% 20combinations) fand keine existierende Lösung ... wie [dies] (http://stackoverflow.com/questions/774457/combination-generator-in-linq) –

+0

Ist 'generateCombinations' eine andere Funktion oder ein Rechtschreibfehler? – Groo

Antwort

0

Ist das die Sache, nach der Sie suchen?

public IEnumerable<string> GetCombinations(IEnumerable<string> source) 
{ 
    if (source == null || !source.Any()) 
    { 
     return Enumerable.Empty<string>(); 
    } 
    else if (source.Skip(1).Any()) 
    { 
     return new string[] { null, source.First() }.SelectMany(x => GetCombinations(source.Skip(1)), (x, y) => x + y); 
    } 
    else 
    { 
     return new string[] { null, source.First() }; 
    } 
} 

Ich kann es wie folgt verwendet werden:

var combinations = GetCombinations(new[] { "0", "1", "2", }); 

Und ich dieses Ergebnis:

 
null 
2 
1 
12 
0 
02 
01 
012