你的问题有点不清楚。
你说组合。组合只是每个可用选项的列表。例如,您有数组 { 1, 2, 3 },并且您希望组合长度为 2,您将获得数组:
{ 1, 2 }
{ 1, 3 }
{ 2, 3 }
您可能指的是排列。排列是每个顺序中的每个组合。因此,从{ 1, 2, 3 } 之前的相同数组开始,所有长度为 2 的排列是:
{ 1, 2 }
{ 1, 3 }
{ 2, 1 }
{ 2, 3 }
{ 3, 1 }
{ 3, 2 }
要获得所有排列而不考虑数组长度,您需要先找到组合并计算排列。
无论您指的是哪个选项,这里有几个有用的扩展方法。
using System;
using System.Collections.Generic;
using System.Linq;
public static class IEnumerableExtensions
{
// Can be used to get all combinations at a certain level
// Source: http://stackoverflow.com/questions/127704/algorithm-to-return-all-combinations-of-k-elements-from-n#1898744
public static IEnumerable<IEnumerable<T>> Combinations<T>(this IEnumerable<T> elements, int k)
{
return k == 0 ? new[] { new T[0] } :
elements.SelectMany((e, i) =>
elements.Skip(i + 1).Combinations(k - 1).Select(c => (new[] { e }).Concat(c)));
}
private static IEnumerable<TSource> Prepend<TSource>(this IEnumerable<TSource> source, TSource item)
{
if (source == null)
throw new ArgumentNullException("source");
yield return item;
foreach (var element in source)
yield return element;
}
// This one came from: http://stackoverflow.com/questions/774457/combination-generator-in-linq#12012418
public static IEnumerable<IEnumerable<TSource>> Permutations<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
throw new ArgumentNullException("source");
var list = source.ToList();
if (list.Count > 1)
return from s in list
from p in Permutations(list.Take(list.IndexOf(s)).Concat(list.Skip(list.IndexOf(s) + 1)))
select p.Prepend(s);
return new[] { list };
}
}
获取排列
听起来您只想获取组合的所有排列(在您的情况下为 PossibleTargets)。
foreach (var permutation in PossibleTargets.Permutations())
{
List<Card> Targets = new List<Card>(permutation);
Out.Add(new GameDecision() { Type = GameDecisionType.PlayCard, TheCard = SpellCard, Targets = Targets });
}
获取组合
如果您实际上是指组合,那么您还需要提供要求解的结果数组的长度。您将其指定为X,但您的代码中没有说明X 可能是什么。要使其正常工作,X 必须小于 Permutations.Count(),否则您将始终得到由列表中每个元素组成的恰好 1 个组合。
var length = X;
foreach (var combination in PossibleTargets.Combinations(length))
{
List<Card> Targets = new List<Card>(combination);
Out.Add(new GameDecision() { Type = GameDecisionType.PlayCard, TheCard = SpellCard, Targets = Targets });
}
一种常见的做法是循环遍历所有可能的长度(从 Combinations.Length 到 1),以获得任意长度的所有可能组合。
for (var length = PossibleTargets.Count(); length > 0; length--)
{
foreach (var combination in PossibleTargets.Combinations(length))
{
List<Card> Targets = new List<Card>(combination);
Out.Add(new GameDecision() { Type = GameDecisionType.PlayCard, TheCard = SpellCard, Targets = Targets });
}
}
获取每个长度的所有排列
此示例获取所有可能长度的每个排列(以任意顺序组合卡片)。
for (var length = PossibleTargets.Count(); length > 0; length--)
{
foreach (var combination in PossibleTargets.Combinations(length))
{
foreach (var permutation in combination.Permutations())
{
List<Card> Targets = new List<Card>(permutation);
Out.Add(new GameDecision() { Type = GameDecisionType.PlayCard, TheCard = SpellCard, Targets = Targets });
}
}
}