2016-03-30 12 views
1

ich etwas mit jeder Kombination von ternären für N Variablen zu tun:Just in time Berechnung von Kombinationen

Beispiel mit 1:

T 
F 
U 

Beispiel mit 2:

TT 
FT 
UT 
TF 
FF 
UF 
UU 

Ist es gibt eine Möglichkeit, dies aber nur nach Bedarf zu berechnen: Zum Beispiel:

var combinator = new Combinator<string>(2, {"T","F","U"}); 
    List<String> tt = combinator.Next(); 
    //tt contains {"T","T"} 
+2

Die einfachste Lösung wäre zu comput e es ist jedoch, Sie berechnen es derzeit, aber verwenden Sie eine Rendite. –

+0

Ich verstehe nicht, wie Sie Ihre Kombinationen ausarbeiten. Sie haben "FT" und "TF", aber Sie haben "UT" und keine "TU". –

Antwort

3

Sie können es in einem Iteratormethode implementieren:

private IEnumerable<List<T>> Combinations<T>(int n, T[] values) 
{ 
    if (n == 0) yield return new List<T>(); 
    else 
    { 
     foreach (var list in Combinations(n - 1, values)) 
      foreach (var item in values) 
      { 
       var items = new List<T>(list); 
       items.Add(item); 
       yield return items; 
      } 
    } 
} 

Dies schafft alle Kombinationen, aber tut es auf eine faule Art und Weise.

Wenn Sie möchten, dass Sie Combinator Klasse wie folgt erstellen:

class Combinator<T> 
{ 
    IEnumerator<List<T>> enumerator; 

    public Combinator(int n, T[] values) 
    { 
     enumerator = Combinations(n, values).GetEnumerator(); 
    } 

    public List<T> Next() 
    { 
     return enumerator.MoveNext() ? enumerator.Current : null; 
    } 

    private IEnumerable<List<T>> Combinations<T>(int n, T[] values) { ... } 
} 
2

wahrscheinlich nicht die rechnerisch effizient, aber es ist Kombinatorik, so dass die Komplexität wahrscheinlich schrecklich steckt sein:

public static IEnumerable<List<T>> Combinations<T>(int count, IEnumerable<T> items) 
{ 
    if(count <= 0) yield break; 
    if(count == 1) 
    { 
     foreach(var item in items) yield return new List<T> { item }; 
     yield break; 
    } 

    foreach(var item in items) 
    { 
     foreach(var combo in Combinations<T>(count - 1, items)) 
     { 
      var result = new List<T> { item }; 
      result.AddRange(combo); 
      yield return result; 
     } 
    } 
} 
0

du die cominations etwas Ordnung, indem sie erreichen könnte, so dass Sie im Grunde eine Zuordnung zwischen ihnen zuweisen und die Zahlen von 1 bis n^m (wobei n die Länge der Permutationen und m die Anzahl der Strings ist). Dann den Staat retten.

Was dies jedoch tut, ist IEnumerable bethisch reimplementieren. https://msdn.microsoft.com/de-de/library/system.collections.ienumerable(v=vs.110).aspx

Noch einfacher, wenn Sie dies in einer Art von foreach-Schleife benötigen, wäre nur eine Methode, die IEnumerable zurückgibt. IEnumerable wird nur langsam ausgewertet, wenn Sie die Yield-Syntax verwenden. http://www.dotnetperls.com/yield

1

Es ist nicht klar, wie Sie Ihre Kombinationen von TFU bekommen.

Sie listen nur die folgenden:

TT 
FT 
UT 
TF 
FF 
UF 
UU 

jedoch, dass zwei Kombinationen fehlt, und es sollte wie folgt (soweit ich arbeiten können) sein:

TT 
FT 
UT 
TF 
FF 
UF 
TU 
FU 
UU 

Unter der Annahme, dass die Letzteres ist eigentlich die richtige Liste, dann können Sie es wie folgt auf "on demand" berechnen: