我正在寻找获得列表项的所有组合的方法。 我的想法是有一个二维数组,类似于位图 例如bit [] [] mybitmap;
例如,如果我的列表中有4个项目“A,B,C,D” 我希望我的位图像这样填充
A B C D
0, 0, 0, 1 --> D
0, 0, 1, 0 --> C
0, 0, 1, 1 --> C, D
0, 1, 0, 0 --> B
0, 1, 0, 1
0, 1, 1, 0
0, 1, 1, 1
1, 0, 0, 0
1, 0, 0, 1
1, 0, 1, 0
1, 0, 1, 1 --> A, C, D
1, 1, 0, 0
1, 1, 0, 1
1, 1, 1, 0
1, 1, 1, 1 --> A, B, C, D
但是如何编写一些C#代码来填充我的位图? (PS:我的清单可能有大约80到90的项目,而不是100到200,刚刚确认)
由于
答案 0 :(得分:2)
所以...只需要从1到15(=(2 ^ n)-1)计数,然后写成二进制,也许使用移位操作。
对于小数字来说这是理智的......但是很快就变得相当大。对于64件物品,你可以在很长的时间内进行建模,但这是18,446,744,073,709,551,615种组合...提示:你永远不会,永远不会那么循环。
对于小案例:
int n = 4;
int max = 1 << n;
for (long val = 1; val < max; val++)
{
long mask = 1 << (n - 1);
for (int bit = 0; bit < n; bit++)
{
bool set = (val & mask) != 0;
Console.Write(set ? "1 " : "0 ");
mask >>= 1;
}
Console.WriteLine();
}
答案 1 :(得分:1)
同意Marc Gravell。您不能假装生成类似于您描述的列表,然后收集您需要的元素。 我一直在做类似的事情,但我只需要所有组合的子集,所以我在列表生成过程中过滤了我的元素。这样,每次递归迭代(我使用F#)都不会创建我已经知道将在最后被丢弃的元素。
通过这种方法,我可以执行200个元素的变体并获得有效结果列表(我已经知道它不会那么大......)
如果您感兴趣,您所描述的问题是一个组合问题。 C#here
中有一篇很好的文章答案 2 :(得分:0)
我相信您不需要将所有组合存储在内存中。 从具有全零位(第一组合)的阵列开始。要获得下一个组合,只需将1添加到上一个组合的最后一位(它很容易实现操作)。等等。 内存使用率低,支持高达20亿的数字。 :)
private void button1_Click(object sender, EventArgs e)
{
string[] items = {"A", "B", "C", "D"};
bool[] bits = new bool[items.Length];
for (int i = 0; i < bits.Length; i++)
{
bits[i] = false;
}
while (!bits.All(x => x))
{
listBox1.Items.Add(string.Join(", ", GetCombination(items, bits)));
AddBit(bits, bits.Length - 1);
}
}
public string[] GetCombination(string[] items, bool[] bits)
{
List<string> combination = new List<string>();
for (int i = 0; i < bits.Length; i++)
{
if (bits[i])
{
combination.Add(items[i]);
}
}
return combination.ToArray();
}
private void AddBit(bool[] bits, int pos)
{
if (pos < 0)
{
// overflow :)
return;
}
if (bits[pos])
{
bits[pos] = false;
AddBit(bits, pos - 1);
}
else
{
bits[pos] = true;
}
}