【问题标题】:combinations of 3 values from an array数组中 3 个值的组合
【发布时间】:2014-06-19 06:51:32
【问题描述】:
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

我写的代码变得非常冗长和混乱,显然有更好的方法。

我尝试使用位于原始数组位置上方的“计数器”,并像这样移动:

1 1 1 0 1 1
c c c
c c     c
c c       c
c   c   c

等等……

【问题讨论】:

  • 您希望有人为您编写它还是您有具体问题?
  • 我猜应该有一种非常基本的递归方法。数组中通常只有 6 个元素吗?
  • 通常数组中的元素会比较多,而且数组会很稀疏,多为0,少数为1。

标签: c# arrays boolean


【解决方案1】:

如果数组相对较短(应该是为了避免内存溢出),您可以使用二进制计数来构建您正在寻找的算法:

  • 假设原始数组有N元素
  • 将数组转换为int,将每个位置视为二进制数字;叫它set
  • 创建一个从 0 到 (1 << N)-1(含)的循环中计数的 mask 数字。此掩码生成所有可能的位组合,可以从原始位中获取
  • 通过对两者进行与运算来生成maskset 的组合:int candidate = mask & set
  • 检查candidate 中设置了多少位
  • 如果设置的位数正好是三个,则将candidate 添加到列表中
  • 循环结束后,您的列表将显示为ints。
  • 消除重复,并根据需要将这些ints 转换为ints 的数组。

这是上述算法的简单实现:

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

Demo on ideone.

【讨论】:

  • @alan2here 见上面的CountBits
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多