如何使用LINQ从一组数字中查找n个项目的所有组合?

我正在尝试编写一种算法来从一组数字中选择n个值的所有组合。

例如,给定集合: 1, 2, 3, 7, 8, 9

该组中2个值的所有组合为:

(1,2),(1,3),(1,7),(1,8),(1,9),(2,3),(2,7),(2,8),(2) ,9),(3,7),(3,8),(3,9),(7,8),(7,9),(8,9)

3是:

(1,2,3),(1,2,7),(1,2,8),(1,2,9),(1,3,7),(1,3,8),(1) ,3,9),(1,7,8),(1,7,9),(1,8,9),(2,3,7),(2,3,8),(2,3) ,(2),(2,7,8),(2,7,9),(2,8,9),(3,7,8),(3,7,9),(3,8,9) ),(7,8,9)

等等!

我目前正在使用方法来产生2,3和4值组合的返回集,但在我看来,这可以在LINQ查询中推广。

谢谢你的帮助!

用法:

 var results = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }.DifferentCombinations(3); 

码:

 public static class Ex { public static IEnumerable> DifferentCombinations(this IEnumerable elements, int k) { return k == 0 ? new[] { new T[0] } : elements.SelectMany((e, i) => elements.Skip(i + 1).DifferentCombinations(k - 1).Select(c => (new[] {e}).Concat(c))); } } 

虽然上面的答案非常简洁但我提出了一个解决方案,根据收集的大小,可以更快。

 static class Combinations { private static void InitIndexes(int[] indexes) { for (int i = 0; i < indexes.Length; i++) { indexes[i] = i; } } private static void SetIndexes(int[] indexes, int lastIndex, int count) { indexes[lastIndex]++; if (lastIndex > 0 && indexes[lastIndex] == count) { SetIndexes(indexes, lastIndex - 1, count - 1); indexes[lastIndex] = indexes[lastIndex - 1] + 1; } } private static List TakeAt(int[] indexes, IEnumerable list) { List selected = new List(); for (int i = 0; i < indexes.Length; i++) { selected.Add(list.ElementAt(indexes[i])); } return selected; } private static bool AllPlacesChecked(int[] indexes, int places) { for (int i = indexes.Length - 1; i >= 0; i--) { if (indexes[i] != places) return false; places--; } return true; } public static IEnumerable> GetDifferentCombinations(this IEnumerable collection, int count) { int[] indexes = new int[count]; int listCount = collection.Count(); if (count > listCount) throw new InvalidOperationException($"{nameof(count)} is greater than the collection elements."); InitIndexes(indexes); do { var selected = TakeAt(indexes, collection); yield return selected; SetIndexes(indexes, indexes.Length - 1, listCount); } while (!AllPlacesChecked(indexes, listCount)); } }