JavaScript中所有可能的唯一组合

时间:2016-02-19 10:20:37

标签: javascript algorithm

我正在构建一个应用来测试不同的图标。管理员上传了许多图标并输入了必须同时显示多少个图标。然后,应用程序按顺序显示所有可能的图标集,直到显示所有图标组合。

现在,我需要一个函数来根据两个数字生成所有独特的图标组合:

  • 总图标数量(i)
  • 每组中的图标数量

如果i = 6且s = 3,我希望输出看起来如下:

[
  [1, 2, 3],
  [1, 2, 4],
  [1, 2, 5],
  [1, 2, 6],
  [1, 3, 4],
  [1, 3, 5],
  [1, 3, 6],
  [1, 4, 5],
  [1, 4, 6],
  [1, 5, 6],
  [2, 3, 4],
  [2, 3, 5],
  [2, 3, 6],
  [2, 4, 5],
  [2, 4, 6],
  [2, 5, 6],
  [3, 4, 5],
  [3, 4, 6],
  [3, 5, 6],
  [4, 5, 6],    
]

要求:

  • 所有套装必须是唯一的
  • 一个数字只能在一组
  • 中出现一次

我一直在尝试编写一个递归函数,但我没有任何东西可以显示。我无法理解它:(

2 个答案:

答案 0 :(得分:2)

n元素与k元素组合在一起,每个元素都不重复,如何操作。 该算法相对简单,主要思想是:我们因此提供第一组k元素,然后尝试从集合的末尾递增每个元素以填充另一个 k-set ,依此类推。 当我们无法做到这一点时,我们就离开了这个过程(所有可能的设置都已准备就绪)。

function combine(n,k) {
  var result = Array();
  var a = Array();

  // make initial (first) k-set
  for (var i=1; i<=k; i++) {
    a[i-1] = i;
  }

  j = k-1;
  while (j >= 1) {

    // submit current results
    result.push(a.slice());

    if (a[k-1] == n) {
      j = j - 1;
    } else {
      j = k-1;
    }

    if (j >= 1) {
      // make next k-set based on previous one
      for (var i=k; i>=j; i--) {
        a[i-1] = a[j-1] + i - j + 1;
      }
    }
  }

  return result;
}

注意:JavaScript数组具有起始索引0,因此在代码中我们对数组索引进行-1校正(导致可能值从1n的集合)

答案 1 :(得分:1)

基于作为这个问题的答案给出的想法: Computing all n-sized permutations without repetitions and without "classic" ordering

  

然后使用C ++ std :: next_permutation作为算法   如下:

     
      
  • 从左边开始,找到最右边的一个,然后是零。放一个
  •   
  • 零位并对阵列的其余部分进行排序。
  •   

免责声明:我的javascript非常非常生疏,所以我确信有一种更优雅的方式来实现它。

function combine(n, k) {
  var result = [];

  // initialize array of values
  var values = [];
  for (var i = 1; i <= n; i++) {
    values[i - 1] = i;
  }

  // initialize permutations
  var perm = [];
  for (var i = 0; i < n; i++) {
    if (i < k) {
      perm[i] = 1;
    } else {
      perm[i] = 0;
    }
  }
  perm.sort();

  whileloop:
    while (true) {
      // save subresult
      var subresult = [];
      for (var i = 0; i < n; i++) {
        if (perm[i] == 1) {
          subresult.push(values[i]);
        }
      }
      result.push(subresult);

      // get next permutation
      for (var i = n - 1; i > 0; i--) {
        if (perm[i - 1] == 1) {
          continue;
        }
        if (perm[i] == 1) {
          perm[i - 1] = 1;
          perm[i] = 0;
          perm = perm.slice(0, i).concat(perm.slice(i).sort())
          continue whileloop;
        }
      }

      // no additional permutations exist
      break whileloop;
    }

  return result;
}