2016-05-12 15 views
0

Es gibt viele Combo-Lösungen für einzelne Arrays oder Vektoren von Arrays, wo Sie jede mögliche Permutation benötigen, aber ich brauche etwas andere Lösung. Ich habe versucht, Stücke zusammen zu hacken, aber ich kann das Holz für die Bäume nicht mehr sehen.C# berechnen Kombinationen von Wörtern aus einer beliebigen Anzahl von Spalten

Ich brauche eine Lösung, die eine CSV-Datei, die bis zu 50 Spalten und eine beliebige Anzahl von Zeilen von Wörtern pro Spalte enthält. Die Anzahl der Zeilen pro Spalte kann unterschiedlich sein.

was ich tun muss, ist diese Eingabe zu nehmen und wiederum durchlaufen jede Spalte ein Wort zu wählen, um jede mögliche Zeilenkombination zu erstellen, überspringt jede Zeile/Spalte, die null ist. Nested Loops würden dies für eine voreingestellte Anzahl von Spalten tun, aber wenn Spalten sich ändern, ist dies ein Problem. ziemlich neu in der Programmierung. Ich hoffe, es ist ein ziemlich einfaches logisches Konzept, das fehlt.

Zum Beispiel:

Eingang:
Bär, Klaue, Krapfen
Huhn, Salat,
Thunfisch ,, Salat

Ausgabe:
Bär, Klaue, Krapfen
Bär, salat, donut
bär, salat
huhn, klaue, donut
Hähnchen, Salat, Krapfen
Huhn, Klaue
Huhn, Salat
Hähnchen, Salat, Krapfen
...
Thunfisch, Klaue, Salat
Thunfisch, Salat etc

+0

Das ist ein wirklich interessantes Problem ... daran zu arbeiten! –

+0

Interessant ist eine interessante Art zu sagen, frustrierend – Dan

+0

Haha, es ist interessanter als frustrierend –

Antwort

0

ich eine Antwort in der gleichen Zeit wie Andrew, aber kurz nach dem Schreiben wurden die Anforderungen unklar, so dass ich darauf verzichtete es zu veröffentlichen. Jetzt, wo sie klar sind, ist hier eine Alternative, die IEnumerable s verwendet. Es muss auch nicht jede Antwort Array.Reverse().

Original-Antworttext

Sie dieses Problem rekursiv lösen wollen.

Der folgende Code geht davon aus, dass Sie die CSV-Datei bereits unter IEnumerable von IEnumerable s analysiert haben.

static void Main() 
{ 
    var wordLists = new List<string[]>() 
    { 
     new string[] { "bear", "chicken", "tuna" }, 
     new string[] { "claw", null, "salad" }, 
     null, 
     new string[] { "donut", "salad", null }, 
    }; 

    foreach (var result in AllPermutations(wordLists)) 
    { 
     System.Console.WriteLine(string.Join(",", result)); 
    } 
} 

// our recursive function. 
private static IEnumerable<IEnumerable<string>> AllPermutations(IEnumerable<IEnumerable<string>> wordLists, int index = 0, List<string> current = null) 
{ 
    if (current == null) 
    { 
     current = new List<string>(); 
    } 

    if (index == wordLists.Count()) 
    { // the end condtion. it is reached when we are past the last list 
     yield return current; 
    } 
    else 
    { // if we are not at the end yet, loop through the entire list 
     // of words, appending each one, then recursively combining 
     // the other lists, and finally removing the word again. 
     var wordList = wordLists.ElementAt(index); 
     if (wordList != null) 
     { 
      foreach (var word in wordList) 
      { 
       if (word == null) continue; 
       current.Add(word); 
       foreach (var result in AllPermutations(wordLists, index + 1, current)) 
       { 
        yield return result; 
       } 
       current.RemoveAt(current.Count - 1); 
      } 
     } 
     else 
     { 
      foreach (var result in AllPermutations(wordLists, index + 1, current)) 
      { 
       yield return result; 
      } 
     } 
    } 
} 

Beachten Sie, dass mit 50 Spalten, könnte es sein, eine Menge von Kombinationen wirklich schnell.

+0

Ich denke, ich mache eine Tabelle, die die größten und kleinsten Wörter aus jeder Zeile, dann mindestens seine nur 2 Zeilen höchstens greift. ienumerable bedeutet mir nichts. Ich kann grundlegende Skripte machen, aber das ... - ich bin kein Entwickler, aber irgendwie ist es auf meinem Schreibtisch gelandet. Kannst du mich auf einen Artikel hinweisen, der zeigt, wie man einen CSV in ein Iserzählbares liest? – Dan

+0

@Dan 'IEnumerable' ist etwas, das Sie aufzählen können (zum Beispiel mit' foreach'). Es wird von vielen Sammlungen implementiert, einschließlich Arrays und 'List's. Wenn Sie es über 'string []' oder 'List ' verwenden, können Sie beides (oder etwas anderes, das es implementiert) übergeben und die Funktion wird korrekt funktionieren. Für das Parsen einer CSV-Datei würde ich vorschlagen, _method 2_ aus [diesem Artikel] (http://danashurst.com/parsing-a-csv-file/) zu verwenden. Schließlich, wenn Sie kein Entwickler sind, glaube ich nicht, dass dies auf Ihrem Schreibtisch gehört. –

+0

Predigen. Ich habe bereits etwas lesen die CSV in eine Liste aber können Sie diese Liste nur in den Parameter Ihrer Funktion übergeben? – Dan

1

Ich bin nicht sicher, wenn ich richtig bin, was du fragst. Sie scheinen einige der Lösungen zu verpassen.

public static IEnumerable<string[]> GetAllCombinations(string[,] input, Stack<string> current = null, int currentCol = 0) 
{ 
    if (current == null) current = new Stack<string>(); 

    var rows = input.GetLength(0); 
    var cols = input.GetLength(1); 

    for (var row = 0; row < rows; row++) 
    { 
     if (input[row, currentCol] == null) continue; 

     current.Push(input[row, currentCol]); 
     if (currentCol == cols - 1) 
     { 
      var result = current.ToArray(); 
      Array.Reverse(result); 
      yield return result; 
     } 
     else 
     { 
      var subResults = GetAllCombinations(input, current, currentCol + 1); 
      foreach (var subResult in subResults) 
       yield return subResult; 
     } 
     current.Pop(); 
    } 
} 

static void Main() 
{ 
    var input = new[,] 
    { 
     {"bear", "claw", "donut"}, 
     {"chicken", "salad", null}, 
     {"tuna", null, "salad"} 
    }; 

    foreach (var comb in GetAllCombinations(input)) 
     Console.WriteLine(string.Join(",", comb)); 
} 

und die Ausgabe:

bear,claw,donut 
bear,claw,salad 
bear,salad,donut 
bear,salad,salad 
chicken,claw,donut 
chicken,claw,salad 
chicken,salad,donut 
chicken,salad,salad 
tuna,claw,donut 
tuna,claw,salad 
tuna,salad,donut 
tuna,salad,salad 
+0

Ignoriere meine vorherigen Kommentare - ich drücke Enter für eine neue Zeile und wusste nicht, dass es den Kommentar eingereicht #noob. Dieser Code scheint ein kleines Kunstwerk zu sein! – Dan

+0

Obwohl ein Problem damit ist, wenn der CSV importiert wird, können Sie die Array-Größe nicht vordefinieren, und da jede Spaltengröße anders ist ... ein Weg um dies zu verwenden ist eine Liste ? – Dan

Verwandte Themen