使用uniq元素将数组拆分为s个子集

时间:2017-03-17 09:19:47

标签: algorithm combinations

给定一个数组[1,2,3,4,5]和数字s代表splits我如何生成以下序列(希望我覆盖s = 3的所有组合)。

它排序的数组和每个子集s必须包含至少1个元素。

s = 2
{1} {2, 3, 4, 5}
{1, 2} {3, 4, 5}
{1, 2, 3}, {4, 5}
{1, 2, 3, 4}, { 5 }
{1, 2, 3, 4, 5}

s = 3
{1}, {2}, {3, 4, 5}
{1}, {2, 3}, {4, 5}
{1}, {2, 3, 4}, {5}
{1, 2}, {3, 4}, {5}
{1, 2, 3}, {4}, {5}
{1, 2}, {3}, {4, 5}
{1, 2, 3}, {4}, {5}

我可以在s=2时解决此问题,但在s>2时不知道该怎么做。

2 个答案:

答案 0 :(得分:1)

我发现您描述的问题是“N代码”中的“m”constant weight代码......

N是单词的长度(在你的情况下5 -1 = 4) m是您想要做的重量或分数(在您的情况下是-s)

字:1 - + - 2 - + - 3 - + - 4 - + - 5 分配位置:1 2 3 4

然后你可以说你的分裂是一个布尔数组(当你想分裂时,分割位置数组中的位为真或1)

所以你有一个代码,你有四个(N-1)个可能的位,总是两个必须为真。  即N = 4且s = 2。

MobileServiceClient client = new MobileServiceClient("https://bruce-chen-002-staging.azurewebsites.net/");
var loginAccount = new LoginAccount()
{
    username = "brucechen",
    password = "123456"
};
await client.CustomLoginAsync(loginAccount);

正如维基百科article所述,没有分析方法来定义任何仲裁组合的可能性数量。但是对于小数字,你可以使用一个简单程序的强力方法。用python编写,它不是最pythonic但更容易阅读。

<强>代码:

[0011],
[0101],
[1001], etc.

<强>输出:

def check(m,N):
    candidates = range(0, 2**(N-1))
    valid_candidates = []
    for candidate in candidates:
        binary_representation = [int(x) for x in list(('{:0%sb}' % (N-1)).format(candidate))]
        if sum(binary_representation) == m:
            #found candidate
            print(binary_representation)
            valid_candidates.append(binary_representation)
    return valid_candidates


if __name__ == "__main__":
    N = 5
    s = 2
    print("Number of valid combinations with N=%s and s=%s is: %s " %(N, s, len(check(s, N))))

答案 1 :(得分:1)

实现这一目标的一种方法是使用递归。像这样的东西(JavaScript代码):

&#13;
&#13;
function f(arr,k){
  if (k === 1)
    return [[arr]];
      
  var result = [];

  for (var i=1; i<=arr.length-k+1; i++){
    var head = arr.slice(0,i),
        tail = arr.slice(i),
        rest = f(tail,k - 1);

    rest.map(x => result.push([head].concat(x)));
  }

  return result;
}

console.log(JSON.stringify(f([1,2,3,4,5],3)));
&#13;
&#13;
&#13;