var example = new[]{1, 1, 1, 0, 1, 1}
我想生成一个所有数组的数组,这个数组在这个数组的位置组合中有三个1,在所有其他位置都有0。
在这个例子中,这些将是:
1 1 1 0 0 0
1 1 0 0 1 0
1 1 0 0 0 1
1 0 1 0 1 0
1 0 1 0 0 1
1 0 0 0 1 1
0 1 1 0 1 0
0 1 1 0 0 1
0 1 0 0 1 1
0 0 1 0 1 1
我编写的代码试图使这变得非常冗长和混乱,显然有更好的方法。
我正在尝试使用' counter'坐在原始阵列的位置上,并像这样移动:
1 1 1 0 1 1
c c c
c c c
c c c
c c c
等...
答案 0 :(得分:2)
如果数组相对较短(应避免溢出内存),您可以使用二进制计数来构建和寻找您正在寻找的算法:
N
个元素int
,将每个位置视为二进制数字;称之为set
mask
个数字,该数字在从0到(1 << N)-1
的循环中计数。该掩码产生可以从原始mask
和set
的组合:int candidate = mask & set
candidate
candidate
添加到列表int
s。int
转换为int
的数组。以下是上述算法的简单实现:
static uint FromArray(int[] data) {
uint res = 0;
for (int i = 0 ; i != data.Length ; i++) {
if (data[i] == 1) {
res |= (1U << i);
}
}
return res;
}
static int[] ToArray(uint set, int size) {
var res = new int[size];
for (int i = 0 ; i != size ; i++) {
if ((set & (1U << i)) != 0) {
res[i] = 1;
}
}
return res;
}
static int CountBits(uint set) {
int res = 0;
while (set != 0) {
if ((set & 1) != 0) {
res++;
}
set >>= 1;
}
return res;
}
public static void Main() {
var example = new[]{1, 1, 1, 0, 1, 1};
var set = FromArray(example);
int N = example.Length;
var res = new List<uint>();
for (uint mask = 0 ; mask != 1U<<N ; mask++) {
var candidate = set & mask;
if (CountBits(candidate) == 3) {
res.Add(candidate);
}
}
foreach (var s in res.Distinct()) {
var array = ToArray(s, N);
Console.WriteLine(string.Join(" ", array.Select(i => i.ToString()).ToArray()));
}
}
此代码生成以下输出:
1 1 1 0 0 0
1 1 0 0 1 0
1 0 1 0 1 0
0 1 1 0 1 0
1 1 0 0 0 1
1 0 1 0 0 1
0 1 1 0 0 1
1 0 0 0 1 1
0 1 0 0 1 1
0 0 1 0 1 1