使用javascript输出数字数组的每个组合

使用javascript输出数字数组的每个组合,javascript,combinations,Javascript,Combinations,我在一个数组中有几个数字 var numArr = [1, 3, 5, 9]; 我想循环遍历该数组,并按如下方式乘以每个唯一的3个数字组合: 1 * 3 * 5 = 1 * 3 * 9 = 1 * 5 * 9 = 3 * 5 * 9 = function combinations(numArr, choose, callback) { var n = numArr.length; var c = []; var inner = function(start, c

我在一个数组中有几个数字

var numArr = [1, 3, 5, 9];
我想循环遍历该数组,并按如下方式乘以每个唯一的3个数字组合:

1 * 3 * 5 = 
1 * 3 * 9 = 
1 * 5 * 9 = 
3 * 5 * 9 =
function combinations(numArr, choose, callback) {
    var n = numArr.length;
    var c = [];
    var inner = function(start, choose_) {
        if (choose_ == 0) {
            callback(c);
        } else {
            for (var i = start; i <= n - choose_; ++i) {
                c.push(numArr[i]);
                inner(i + 1, choose_ - 1);
                c.pop();
            }
        }
    }
    inner(0, choose);
}
然后返回所有计算的数组

var ansArr = [15,27,45,135];

有人有优雅的解决方案吗?提前谢谢。

我认为这应该可以:

var a = [1, 3, 5, 9];
var l = a.length;
var r = [];
for (var i = 0; i < l; ++i) {
  for (var j = i + 1; j < l; ++j) {
    for (var k = j + 1; k < l; ++k) {
      r.push(a[i] * a[j] * a[k]);
    }
  }
}
var a=[1,3,5,9];
var l=a.长度;
var r=[];
对于(变量i=0;i
编辑

只是为了我自己的启发,我想出了一个使用循环而不是递归的通用解决方案。它明显的缺点是它的时间更长,因此加载或读取速度较慢。另一方面(至少在我机器上的Firefox上),它的运行速度大约是递归版本的两倍。但是,我只建议您查找大型集合的组合,或者在同一页面上多次查找组合。不管怎么说,如果有人感兴趣,这是我的想法

function combos(superset, size) {
  var result = [];
  if (superset.length < size) {return result;}
  var done = false;
  var current_combo, distance_back, new_last_index;
  var indexes = [];
  var indexes_last = size - 1;
  var superset_last = superset.length - 1;

  // initialize indexes to start with leftmost combo
  for (var i = 0; i < size; ++i) {
    indexes[i] = i;
  }

  while (!done) {
    current_combo = [];
    for (i = 0; i < size; ++i) {
      current_combo.push(superset[indexes[i]]);
    }
    result.push(current_combo);
    if (indexes[indexes_last] == superset_last) {
      done = true;
      for (i = indexes_last - 1; i > -1 ; --i) {
        distance_back = indexes_last - i;
        new_last_index = indexes[indexes_last - distance_back] + distance_back + 1;
        if (new_last_index <= superset_last) {
          indexes[indexes_last] = new_last_index;
          done = false;
          break;
        }
      }
      if (!done) {
        ++indexes[indexes_last - distance_back];
        --distance_back;
        for (; distance_back; --distance_back) {
          indexes[indexes_last - distance_back] = indexes[indexes_last - distance_back - 1] + 1;
        }
      }
    }
    else {++indexes[indexes_last]}
  }
  return result;
}

function products(sets) {
  var result = [];
  var len = sets.length;
  var product;
  for (var i = 0; i < len; ++i) {
    product = 1;
    inner_len = sets[i].length;
    for (var j = 0; j < inner_len; ++j) {
      product *= sets[i][j];
    }
    result.push(product);
  }
  return result;
}

console.log(products(combos([1, 3, 5, 7, 9, 11], 3)));
函数组合(超集、大小){
var结果=[];
if(superset.length-1;--i){
距离_back=索引_last-i;
新的上次索引=索引[上次索引-返回距离]+返回距离+1;

如果(new_last_index生成组合的通用算法如下所示:

1 * 3 * 5 = 
1 * 3 * 9 = 
1 * 5 * 9 = 
3 * 5 * 9 =
function combinations(numArr, choose, callback) {
    var n = numArr.length;
    var c = [];
    var inner = function(start, choose_) {
        if (choose_ == 0) {
            callback(c);
        } else {
            for (var i = start; i <= n - choose_; ++i) {
                c.push(numArr[i]);
                inner(i + 1, choose_ - 1);
                c.pop();
            }
        }
    }
    inner(0, choose);
}
…对于给定的输入,产生以下结果:

15,21,27,33,35,45,55,63,77,99,105,135,165,189,231,297,315,385,495,693

一个递归函数,当您需要在n个数字中选择k个数字时可以执行此操作。尚未测试。请查找是否存在任何错误并更正:-)

var结果=[];
foo(arr,0,1,k,n);//初始调用
函数foo(arr、s、mul、k、n){
如果(k==1){
结果:推送(mul);
返回;
}
var i;

对于(i=s;i使用node,您可以使用库轻松完成此操作。首先,使用npm安装
位旋转

npm install bit-twiddle
然后您可以在代码中使用它,如下所示:

//Assume n is the size of the set and k is the size of the combination
var nextCombination = require("bit-twiddle").nextCombination
for(var x=(1<<(k+1))-1; x<1<<n; x=nextCombination(x)) {
   console.log(x.toString(2))
}
//假设n是集合的大小,k是组合的大小
var nextcomposition=require(“位旋转”)。nextcomposition
对于(var x=(1
var create3Combi=函数(数组){
var结果=[];
map(函数(item1,index1){
map(函数(item2,index2){
对于(var i=index2+1;i

找到此库。测试结果正常。以下是库文档中的内容:

var Combinatorics = require('js-combinatorics');
var cmb = Combinatorics.combination(['a','b','c','d'], 2);
while(a = cmb.next()) console.log(a);
//  ["a", "b"]
//  ["a", "c"]
//  ["a", "d"]
//  ["b", "c"]
//  ["b", "d"]
//  ["c", "d"]

在标题中你要求排列,但在正文中你提到了组合。是哪一种?(我猜的是组合,因为乘法是可交换的。)@DaveKingsnorth注意:数组中有字符串,而不是数字。@Sime Vidas-那是个错误,它们应该是数字而不是数字strings@DaveKingsnorth数组中的数字是不同的吗?@Sime Vidas-不总是,如果我想得到所有2个数字组合或5个数字组合,数组中可能会有重复的数字(如果我有一个较长的数组),是否有一个解决方案可以将该值指定为变量(我指的是指定组合的长度)@DaveKingsnorth如果你想改变这一点,那么我的解决方案太具体了。请看Marcelo更一般的解决方案。你的解决方案实际上回答了我最初的问题,但Marcelo的解决方案正是我想要的。谢谢你的输入。@Niraj-你能解释一下每个参数是什么吗?这是一个递归函数。1)第一个参数是数组arr。2)第二个参数是整数s。每个调用从索引s开始计算数组部分的值。我递归地增加s,因此每个调用的数组递归地变小。3)第三个参数是递归计算并在递归调用中传递的值。当k变为1时,它将添加到结果数组中。4)k表示所需的组合大小。它递归地减小,当变为1时,输出追加到结果数组中。5)n是数组arr的大小。实际上,n=arr.length这是我所想的,但我仍然在某处出错。我调用的函数如下:var arr=[2,1,4,1,6];foo(arr,0,1,4,5);然后像这样输出:document.write(result);我做错了什么?
var Combinatorics = require('js-combinatorics');
var cmb = Combinatorics.combination(['a','b','c','d'], 2);
while(a = cmb.next()) console.log(a);
//  ["a", "b"]
//  ["a", "c"]
//  ["a", "d"]
//  ["b", "c"]
//  ["b", "d"]
//  ["c", "d"]