【问题标题】:All possible unique combinations of a set in JavaScriptJavaScript 中集合的所有可能的唯一组合
【发布时间】:2016-02-19 10:20:36
【问题描述】:

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

现在,我需要一个函数来生成基于两个数字的所有唯一图标组合:

  • 图标总数 (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],    
]

要求:

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

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

【问题讨论】:

标签: javascript algorithm


【解决方案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;
}

【讨论】:

    【解决方案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 的一组可能值)

    【讨论】:

    • combine(4,2) 产生 3 个变体而不是 6 个
    猜你喜欢
    • 2012-03-27
    • 1970-01-01
    • 1970-01-01
    • 2013-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-27
    • 2015-08-11
    相关资源
    最近更新 更多