如何在Javascript中输出数组中30个不同数字的7个数字的所有可能组合?

时间:2015-08-23 20:07:07

标签: javascript arrays algorithm combinations subset

例如,我使用这样的循环生成数组。

var array=[];
for(var i=1; i<=30; i++)
  {
   array.push(i);

  }
 console.log(array);

我想输出数组中所有可能的7个数字组的组合。例如,示例输出可能如下所示:[1,5,14,4,30,23,19]。如果我想用组合公式计算可能的组合。它会是这样的: N!/ R!(N-R)!

这将是一个巨大的数字。我找到了permutation solution here, 但它的作用是根据数组的长度打印出所有可能的数字。但我需要找出总共30个整数中7个数字的可能组合。

如何使用javascript在逻辑上和实际上解决这个问题。

2 个答案:

答案 0 :(得分:0)

首先:这将产生bincoef(7,30)个整数集,大约为2十亿。设置,所以你应该考虑是否需要这么多的数据,因为这个算法会产生大量的数据,并且需要大量的数据。我只能提供伪代码,因为我的javascript知识非常基础。

void nextPermutation(int[] in, int[] set, int last_from_input, int at_element)
    //we can't generate further permutations from this position, since
    //there is aren't enough elements in the input-array left
    if(last_from_input >= 30 - at_element)
        return

    //the set is filled -> process the produced set
    if(at_element === 7)
        print(set)//process permutation
        return

    //add one element to the set and proceed with further elements
    for(int i in ]last_from_input, length(in) - (7 - at_element)[
        set[at_element] = in[i]

        nextPermutation(in , set , i, at_element + 1)

基本上这个算法得到以下参数:

  • in:要从中选择的30个整数
  • set:包含我们目前添加的所有元素的petmutation的当前部分
  • last_from_input:我们添加到set
  • 中的最后一个元素的索引
  • at_element:我们当前正在搜索的集合中的元素索引

该算法基本上添加了一个索引比最后添加的元素更高的元素,并继续搜索递归搜索下一个元素。如果集合完成,则可以进行处理。如果完成集合所需的元素多于其中剩余的元素,则无法完成集合,我们可以在这部分搜索中断。这不是关于效率的最佳实现,但我试图保持简单

现在我们可以通过这种方式简单地生成所有排列:

void genPermutations(int[] in)
    nextPermutation(in , new int[7],-1,0)

答案 1 :(得分:0)

猜猜这就是你要追求的目标?

function cartesian_product(xs, ys) {
    var result = [];
    for(var i = 0; i < xs.length; i++) {
        for (var j = 0; j < ys.length; j++) {
            // transform [ [1, 2], 3 ] => [ 1, 2, 3 ] and append it to result []
            result.push([].concat.apply([], [ xs[i], ys[j] ]));
        }
    }
    return result;
}

function cartesian_power(xs, n) {
    var result = xs;
    for(var i = 1; i < n; i++) {
        result = cartesian_product(result, xs)
    }
    return result;
}

// in your case params are [ 1, 2... 30] and 7
console.log(cartesian_power([1, 2, 3, 4], 2));

输出是:

[ [ 1, 1 ],
  [ 1, 2 ],
  [ 1, 3 ],
  [ 1, 4 ],
  [ 2, 1 ],
  [ 2, 2 ],
  [ 2, 3 ],
  [ 2, 4 ],
  [ 3, 1 ],
  [ 3, 2 ],
  [ 3, 3 ],
  [ 3, 4 ],
  [ 4, 1 ],
  [ 4, 2 ],
  [ 4, 3 ],
  [ 4, 4 ] ]

<强>更新

这个将需要更少的内存,因为它不会存储任何东西,它只会打印输出。但仍然怀疑它是否实用。

function print_combs(arr, n, out) {
    if (n === 0) {
        console.log(out);
    } else {
        for(var i = 0; i < arr.length; i++) {
            print_combs(arr, n-1, out+arr[i]);
        }
    }
}

print_combs([1, 2, 3, 4], 2, "");