假设我输入了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 };
答案 0 :(得分: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);
}
答案 1 :(得分: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);
答案 2 :(得分: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]);
但我的眼睛不太可读。
请注意,与其他方法相比,效率稍差,因为它首先获得所有可能的组合,然后减少不需要的组合。然而,简单的单行。