n个元素的组合选择r元素而不重复(Objective-c)

时间:2013-11-28 02:58:03

标签: ios objective-c c combinations

我有一个对象数组(n)。 我想通过一次选择(r)元素来输出一组唯一对象。

例如: n = 600, r = 10

我们如何获得所有可能的独特解决方案?

我意识到这是二项式系数公式(并且解决方案集也是巨大的),但我无法找到实现它的方法,不会超出内存约束。

可能有助于实现细节的内容(来自内存问题)是对于每种可能的组合,我可以应用某些规则来确认它是否与我有任何关系(在很多情况下组合将会没用)。

1 个答案:

答案 0 :(得分:1)

这是一个简单的算法,如果你足够多次调用,它可以让你产生从0到n-1的整数的所有r组合。该算法所做的是采用表示组合的r向量,并将其就地推进到下一个组合(按字典顺序)。您可以使用这样的矢量来索引对象的矢量。

给出一个向量v0...vr-1

  • 找到最大的j < r vj < n - r + j
  • 增量元素j
  • 对于每个k j < kk < r,请将vk设置为vj + k - j

这是一个简单而合理有效的C解决方案(虽然不是每个人都会欣赏这种风格)。如果当前组合是最后一个组合,则函数返回false。应该将向量初始化为序列0...r-1,以便迭代整个可能性集。

bool next_combination(int *comb, int n, int r) {
  for (int j = r - 1, v = n - 1; j >= 0; --j, --v) {
    if (comb[j] < v) {
      for (v = comb[j] + 1; j < r; ++j, ++v)
        comb[j] = v;
      return true;
    }
  }
  return false;
}

但是,我真的不认为生成所有可能的 600 C 10 值是切实可行的,即使你不尝试将它们全部存储在一个数组中。 600 C 10 是1,545,269,050,621,668,869,640。如果你可以在一秒内处理10个 9 组合(即每纳秒一个),那么通过整个列表仍然需要大约48,965年。

因此,您可能想要考虑如何只生成您感兴趣的组合。