2016-05-12 12 views
0

可能なすべての並べ替えが必要な配列の単一配列またはベクトルには、多くのコンボソリューションがありますが、少し異なるソリューションが必要です。アイブは断片を一緒にハックしようとしましたが、もはや木の木が見えません。C#任意の数の列から単語の組み合わせを計算する

私は、最大50の列と1列あたりの任意の数の行の行を含むcsvファイルを取るソリューションが必要です。 1列あたりの行数は異なる場合があります。

私はこの入力を受け取り、すべての行の組み合わせを作成するために1つの単語を選択して各行を繰り返し、nullの行/列をスキップします。ネストされたループはプリセットされた列数に対してこれを行いますが、列が変わるとこれが問題になります。かなり新しいプログラミングです。かなり簡単な論理的概念が失われることを望んでいる。例えば

入力:
クマ、爪、ドーナツ
チキン、サラダ、
マグロ,,サラダ

出力:
クマ、爪、ドーナツ
クマ、サラダ、ドーナツ
クマ、サラダ
チキン、クロー、ドーナツ
チキン、サラダ、ドーナツ
鶏肉、
チキン、サラダ
チキン、サラダ、ドーナツを爪
...
マグロ、爪、サラダ
マグロ、サラダ私はありません など

+0

これは本当に興味深い問題です...それに取り組んでいます! –

+0

興味深いのは面白いと言っても面白いです – Dan

+0

ハハ、それはイライラより面白いよ –

答えて

0

私はAndrewと同時に答えを書いていたが、直後に、要件が不明確になったので、私はそれを投稿控え。それらが明確であるので、IEnumerableを使用する代替案がここにあります。また、回答ごとにArray.Reverse()は必要ありません。

オリジナル解答テキスト

あなたは再帰的にこの問題を解決したいと思うでしょう。

次のコードでは、CSVを既にIEnumerableの部分をIEnumerableに解析していることを前提としています。

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; 
      } 
     } 
    } 
} 

50列で、本当に速いの組み合わせのたくさんがあるかもしれないことに注意してください。

+0

私は、悪いと思うのは、各行の最大と最小の単語をつかみ、それから少なくともわずか2行です。 ienumerableは私に何も意味しません。私は基本的なスクリプティングを行うことができますが、これは... - 私は開発者ではなく、何とか私の机の上に着陸しました。 csvをienumerableに読み込む方法を示す記事を教えてください。 – Dan

+0

@Dan 'IEnumerable'は列挙できるものです(例えば' foreach'を使って)。配列や 'List'を含む多くのコレクションによって実装されています。 'string []'や 'List 'を使ってみると、どちらか一方(あるいはそれを実装するもの)を渡すことができ、関数は正しく動作します。 CSVファイルの解析については、[この記事](http://danashurst.com/parsing-a-csv-file/)の_method 2_を使用することをお勧めします。最後に、あなたが開発者でない場合、私はこれがあなたの机の上にあるとは思わない。 –

+0

説教。私は既にリストにCSVを読んで何かを持っていますしかし、あなたはあなたの関数のパラメータにそのリストを渡すことはできますか? – Dan

1

あなたが求めているものが正しいかどうか確かめてください。あなたは解決策のいくつかが欠けているようです。

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)); 
} 

と出力:

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

私の前のコメントを無視する - 私は新しい行のために入力して、それがコメント#noobを提出したことを知らなかった。このコードはちょっとした芸術のようです! – Dan

+0

この問題は、csvをインポートするときに発生しますが、配列のサイズを事前に定義することはできません。また、各列のサイズが異なるため... リストを使用する方法はありますか? – Dan

関連する問題