我需要创建一个数字组合列表。数字很小,所以我可以用byte
代替int
。但是,它需要许多嵌套循环才能获得所有可能的组合。我想知道是否有一种更有效的方式来执行我要执行的操作。到目前为止的代码是:
var data = new List<byte[]>();
for (byte a = 0; a < 2; a++)
for (byte b = 0; b < 3; b++)
for (byte c = 0; c < 4; c++)
for (byte d = 0; d < 3; d++)
for (byte e = 0; e < 4; e++)
for (byte f = 0; f < 3; f++)
for (byte g = 0; g < 3; g++)
for (byte h = 0; h < 4; h++)
for (byte i = 0; i < 2; i++)
for (byte j = 0; j < 4; j++)
for (byte k = 0; k < 4; k++)
for (byte l = 0; l < 3; l++)
for (byte m = 0; m < 4; m++)
{
data.Add(new [] {a, b, c, d, e, f, g, h, i, j, k, l, m});
}
我当时正在考虑使用类似a的东西,BitArray
但是我不确定如何合并它。
任何建议将不胜感激。或者,也许这是我想要做的最快的方法?
编辑 几个要点(抱歉,我没有在原始帖子中提到):
- 数字和它们的顺序(2、3、4、3、4、3、3等)非常重要,因此使用诸如使用LINQ生成置换的解决方案将无济于事,因为每个“列”中的最大值不同
- 我不是数学家,所以如果我没有正确使用“排列”和“组合”等技术术语,我深表歉意:)
- 我确实需要一次填充所有这些组合-我不能仅仅基于索引来获取一个或多个
- 我保证使用
byte
比使用更快。拥有67m +字节数组而不是整数在内存使用方面也要好得多int
- 我的最终目标是寻找一种更快的嵌套循环替代方法。
- 我考虑过使用并行编程,但是由于要实现的迭代性质,我找不到成功的方法(即使使用
ConcurrentBag
),但是很高兴被证明是错误的:)
结论
Caramiriel提供了很好的微观优化,可节省一些时间,因此,我将该答案标记为正确。Eric还提到预分配列表更快。但是,在这个阶段,嵌套循环似乎实际上是最快的方法(令人沮丧,我知道!)。
如果您想尝试使用的基准测试StopWatch
,请使用13个循环,每个循环最多计数4个循环-列表中约有67m +行。在我的机器(i5-3320M 2.6GHz)上,大约需要2.2s来完成优化版本。