2

次のコードを検討してください。

List<string> a = new List<string>(new string[] { "a1", "a2" });
List<string> b = new List<string>(new string[] { "b1", "b2" });
List<string> c = new List<string>(new string[] { "c1", "c2" });
List<List<string>> input = new List<List<string>>();
input.Add(a);
input.Add(b);
input.Add(c);
List<List<string>> output=List<List<string>> PickOneFromEachSet(input)

PickOneFromEachSet順序を考慮せずに各セットから要素を選択します。

2^3=8 通りの組み合わせが可能です。つまり、出力は次のようになります。

{"a1","b1","c1"},
{"a1","b1","c2"},
...
{"a2","b2","c2"}

そのような関数をどのように構築すればよいでしょうか?

4

4 に答える 4

6

常に 3 つのセットがある場合、それは簡単です。

var query = from aValue in a
            from bValue in b
            from cValue in c
            select new List<string> { aValue, bValue, cValue };
List<List<string>> output = query.ToList();
于 2012-07-23T12:06:50.953 に答える
3

LINQ を使用したデカルト積の計算を参照してください。

List<string> a = new List<string>(new string[] { "a1", "a2" });
List<string> b = new List<string>(new string[] { "b1", "b2" });
List<string> c = new List<string>(new string[] { "c1", "c2" });

var result = CartesianProduct(new List<List<string>>(){a,b,c});

foreach (var row in result)
{
    foreach (var item in row)
    {
        Console.Write(item + " ");
    }
    Console.WriteLine();
}

//https://svn.apache.org/repos/asf/incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/contrib/SimpleFacetedSearch/Extensions.cs
public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(IEnumerable<IEnumerable<T>> sequences)
{
    IEnumerable<IEnumerable<T>> emptyProduct = new IEnumerable<T>[] { Enumerable.Empty<T>() };
    return sequences.Aggregate(
        emptyProduct,
        (accumulator, sequence) =>
        {
            return accumulator.SelectMany(
                (accseq => sequence),
                (accseq, item) => accseq.Concat(new T[] { item })
            );
        }
    );
}

.NET 3.5

public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(IEnumerable<List<T>> sequences)
{
    //SAME
}

出力:

a1 b1 c1
a1 b1 c2
a1 b2 c1
a1 b2 c2
a2 b1 c1
a2 b1 c2
a2 b2 c1
a2 b2 c2
于 2012-07-23T12:49:26.707 に答える
1

このようなものはどうですか?

public List<T> GetFirstOfEach<T>(params List<T>[] Lists)
{
    List<T> rt = new List<T>();
    Lists.ToList().ForEach(l => rt.Add(l.First()));

    return rt;
}

これにより、好きなだけリストを関数に渡すことができます。

List<string> output = GetFirstOfEach(a, b, c);
于 2012-07-23T12:07:57.180 に答える
0

代わりにこのコードを使用しました。代わりにここに投稿します。

List<string> a = new List<string>(new string[] { "a1", "a2" });
List<string> b = new List<string>(new string[] { "b1", "b2" });
List<string> c = new List<string>(new string[] { "c1", "c2" });

var result = CartesianProduct(new List<List<string>>(){a,b,c});

foreach (var row in result)
{
    foreach (var item in row)
    {
        Console.Write(item + " ");
    }
    Console.WriteLine();
}

     public static List<List<T>> CartesianProduct<T>(List<List<T>> sets)
            {              
                List<List<T>> results = new List<List<T>>();

                int solutions = 1;
                for (int i = 0; i < sets.Count; i++)
                {
                    solutions *= sets[i].Count;
                }
                for (int i = 0; i < solutions; i++)
                {
                    int j = 1;
                    List<T> elem = new List<T>();
                    foreach (List<T> set in sets)
                    {
                        elem.Add(set[(i / j) % set.Count]);
                        j *= set.Count;
                    }
                    results.Add(elem);
                }
                return results;
            }

出力:

a1 b1 c1
a1 b1 c2
a1 b2 c1
a1 b2 c2
a2 b1 c1
a2 b1 c2
a2 b2 c1
a2 b2 c2
于 2012-07-24T01:35:19.030 に答える