鉴于枚举,我想知道如何填充锯齿状数组,以便每个内部数组包含枚举值的组合(枚举中的7个值,内部数组中的6个插槽,允许重复)和外部数组包含每种可能的组合(不是排列;红色红色红色红色橙色和红色红色红色橙色红色是相同的元素)。
多维数组也可以工作,但是考虑到现实问题,锯齿状数组似乎更适用。我很难搞清楚填充它的循环是如何编写的。
语言是C#。我希望以一种方式对其进行填充,以便从最高"顺序对结果进行排序。至"最低"值,(从红色红色红色红色红色红色开始,然后是红色红色红色红色红色橙色等)。这是枚举:
public enum OrderedColors
{
Colorless,
Purple,
Blue,
Green,
Yellow,
Orange,
Red
}
答案 0 :(得分:0)
使用LINQ:
OrderedColors[] colors = (OrderedColors[])Enum.GetValues(typeof(OrderedColors));
OrderedColors[][] matrix = (
from a in colors
from b in colors
from c in colors
from d in colors
from e in colors
from f in colors
select new [] {a,b,c,d,e,f}
).ToArray();
如果你想制作能够产生任何长度组合的东西,那么你需要更复杂的东西。
编辑:您可以通过在以下各项之后添加where子句来修复它:
OrderedColors[][] matrix = (
from a in colors
from b in colors
where a<=b
from c in colors
where b<=c
from d in colors
where c<=d
from e in colors
where d<=e
from f in colors
where e<=f
select new [] {a,b,c,d,e,f}
).ToArray();
答案 1 :(得分:0)
您可以使用简单的递归函数来实现它的可扩展性。它接收要组合的项目数组,要从数组中选择的项目数,以及从数组中选择seleft项目的起始索引(默认为0)。它会在每个允许的起始位置重新选择第一个项目,并将其他元素的所有组合附加到项目数组的右侧。
public static IEnumerable<T[]> BuildCombinations<T>(T[] items, int itemsCountInCombination, int startIndex = 0)
{
if (itemsCountInCombination == 0)
{
yield return new T[0];
yield break;
}
for (int i = startIndex; i < items.Length; i++)
{
foreach (var combination in BuildCombinations(items, itemsCountInCombination - 1, i))
{
var c = new T[itemsCountInCombination];
c[0] = items[i];
Array.Copy(combination, 0, c, 1, combination.Length);
yield return c;
}
}
}
private static void Main(string[] args)
{
foreach (var c in BuildCombinations(Enum.GetValues(typeof (OrderedColors)).Cast<OrderedColors>().Reverse().ToArray(), 6))
{
foreach (var color in c)
{
Console.Write(color);
Console.Write(" ");
}
Console.WriteLine();
}
}
它生成预期的924个组合,重复7个中的6个元素,在0.44ms内。它可能不是最好的性能,并且它使用的内存比可能的多,但它的实现非常简单,而且对于这么多元素来说足够高效。
答案 2 :(得分:0)
我发现这个问题很有意思,并继续致力于解决方案......在这里你去......
使用像这样的代码......
var example = new[] {
OrderedColors.Red, OrderedColors.Orange, OrderedColors.Yellow,
OrderedColors.Green, OrderedColors.Blue, OrderedColors.Purple,
OrderedColors.Colorless };
var combinations = example.CombinationsWithRepetition(6);
这会产生924个预期的结果,并且不会进行任何不必要的计算或复制。以下是实际方法。
public static IEnumerable<IList<T>> CombinationsWithRepetition<T>
(this IEnumerable<T> input, int take) where T : new()
{
var items = input.ToList();
return CombinationsWithRepetition(items, null, take, 0, 0);
}
private static IEnumerable<IList<T>> CombinationsWithRepetition<T>
(List<T> allItems, IList<T> thisSequence, int maxLength,
int currentLength, int currentIndex)
{
if (maxLength == 0)
yield return new List<T>();
for (var index = currentIndex; index < allItems.Count; index++)
{
var nextSequence = thisSequence == null ? new List<T>() :
thisSequence.ToList();
nextSequence.Add(allItems[index]);
if (currentLength + 1 == maxLength)
{
yield return nextSequence;
}
else
{
foreach (var sequence in CombinationsWithRepetition(allItems,
nextSequence, maxLength, currentLength + 1, index))
{
yield return sequence;
}
}
}
}
享受!写它很有趣。