1

重複の可能性:
リスト順列 (不明な番号)

入力があるとしましょうRange[1, 8]

{1,2,3,4,5,6,7,8}

そして見つけたいSubsets[%, {2}](正確な長さが2のすべてのサブセット)

{{1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}, {1, 7}, {1, 8}, {2, 3}, {2, 4}, 
 {2, 5}, {2, 6}, {2, 7}, {2, 8}, {3, 4}, {3, 5}, {3, 6}, {3, 7}, {3, 8}, 
 {4, 5}, {4, 6}, {4, 7}, {4, 8}, {5, 6}, {5, 7}, {5, 8}, {6, 7}, {6, 8}, {7, 8}}

試した:

var values = Enumerable.Range(1, 8);
var result = from v in values
             from v2 in values.Skip(v)
             select new[] { v, v2 };
4

3 に答える 3

2

指定されたサイズの入力シーケンスのすべての組み合わせを見つける関数を次に示します。

public static IEnumerable<IEnumerable<T>> Combinations<T>(this IEnumerable<T> source, int n)
{
    if (n == 0)
        yield return Enumerable.Empty<T>();


    int count = 1;
    foreach (T item in source)
    {
        foreach (var innerSequence in source.Skip(count).Combinations(n - 1))
        {
            yield return new T[] { item }.Concat(innerSequence);
        }
        count++;
    }
}

したがって、あなたの場合は次のように使用します。

var result = Enumerable.Range(1, 8).Combinations(2);
于 2012-11-09T16:33:26.140 に答える
2
var query = from a in Enumerable.Range(1, 8)
            from b in Enumerable.Range(a + 1, 8 - a)
            select String.Format("{{{0}, {1}}}", a, b);

foreach (string s in query)
{
    Console.Out.WriteLine(s);
}
于 2012-11-09T16:08:21.603 に答える
1
var lst = Enumerable.Range(1, 8);
var result = lst.Join(lst, c => 1, c => 1, (i, j) => new[] { i, j })
        .Where(c => c[0] < c[1]);

ここでは、条件を使用して1 == 1値の相互結合をEnumerable.Range(1, 8)取得し、すべての可能な組み合わせを取得しました。

コメントに記載されているように、クロス結合を生成する簡単な方法は次のとおりです。

var result = lst.SelectMany(_ => lst, (i, j) => new[] { i, j })
        .Where(c => c[0] < c[1]);

しかし、私の目には読みにくいです。

これは他の方法に比べて少し効率が悪いことに注意してください。これは、最初にすべての可能な組み合わせを取得してから、不要なものを削除するためです。それにもかかわらず、シンプルなワンライナー。

于 2012-11-09T16:28:29.537 に答える