输出的数字阵列与JavaScript
的每个组合我有以阵列几个号码输出的数字阵列与JavaScript
var numArr = [1, 3, 5, 9];
欲循环通过该数组和乘每个唯一的3号组合如下:
1 * 3 * 5 =
1 * 3 * 9 =
1 * 5 * 9 =
3 * 5 * 9 =
然后返回所有的计算阵列
var ansArr = [15,27,45,135];
任何人都有一个优雅的解决方案?提前致谢。
通用算法如下:
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);
}
在你的情况,你可以把它像这样:
function product(arr) {
p = 1;
for (var i in arr) {
p *= arr[i];
}
return p;
}
var ansArr = [];
combinations(
[1, 3, 5, 7, 9, 11], 3,
function output(arr) {
ansArr.push(product(arr));
});
document.write(ansArr);
...其中,用于给定的输入,产生此:
15,21,27,33,35,45,55,63,77,99,105,135,165,189,231,297,315,385,495,693
这太棒了。非常感谢! – DaveKingsnorth 2010-10-31 00:13:38
我认为这应该工作:
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]);
}
}
}
编辑
只是我自己的熏陶,我想通了,使用的,而不是递归循环一个通用的解决方案。显而易见的缺点是,加载或阅读时间较长。另一方面(至少在我的机器上是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)));
完美!非常感谢 – DaveKingsnorth 2010-10-30 23:51:04
如果我想得到所有2个数字组合或5个数字组合(如果我有一个更长的数组),是否有解决方案,我可以指定该值作为变量(我正在谈论指定的长度组合)。 – DaveKingsnorth 2010-10-30 23:59:27
@DaveKingsnorth如果你想改变这一点,那么我的解决方案太具体。参见Marcelo更通用的解决方案。 – 2010-10-31 00:12:31
当您需要在n个数字中选择k个数字时,执行此操作的递归函数。没有测试过。如果发现有任何错误,并纠正它:-)
var result = [];
foo(arr, 0, 1, k, n); // initial call
function foo(arr, s, mul, k, n) {
if (k == 1) {
result.push(mul);
return;
}
var i;
for (i=s; i<=n-k; i++) {
foo(arr, i+1, mul*arr[i], k-1, n-i-1);
}
}
这是一个递归函数。
第一个参数是数组
arr
。第二个参数是整数s
。每次调用都会从索引s
开始计算数组的一部分值。递归地增加s
,因此每个调用的数组递归地变小。第三个参数是递归计算并在递归调用中传递的值。当
k
变为1时,它被添加到结果数组中。k
中所需的组合的尺寸。它递归递减,当成为1时,输出附加在结果数组中。n
是数组大小arr
。其实n = arr.length
@ Niraj - 你能解释一下每一个参数吗? – DaveKingsnorth 2010-10-31 00:57:49
这是一个递归函数。 1)第一个参数是数组arr。 2)第二个参数是整数s。每次调用都会从索引s开始计算数组的一部分值。递归地增加s,所以每个调用的数组递归地变小。 3)第三个参数是递归计算并在递归调用中传递的值。当k变为1时,它被添加到结果数组中。 4)k在所需的组合的大小。它递归递减,当成为1时,输出附加在结果数组中。 5)n是数组arr的大小。其实n = arr.length – 2010-10-31 07:31:37
这就是我的想法,但我仍然在某个地方犯错。我打这样的函数: var arr = [2,1,4,1,6]; foo(arr,0,1,4,5); 并输出它像这样:document.write(result);我究竟做错了什么? – DaveKingsnorth 2010-11-02 00:23:26
使用节点,你可以很容易地使用库来做到这一点。
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))
}
变量x
是一个位向量,其中位i
设置如果i
个元素是第一次使用NPM安装bit-twiddle
包含在组合中。
var create3Combi = function(array) {
var result = [];
array.map(function(item1, index1) {
array.map(function(item2, index2) {
for (var i = index2 + 1; i < array.length; i++) {
var item3 = array[i];
if (item1 === item2 || item1 === item3 || item2 === item3 || index2 < index1) {
continue;
}
result.push([item1, item2, item3]);
}
});
});
return result;
};
var multiplyCombi = function(array) {
var multiply = function(a, b){
return a * b;
};
var result = array.map(function(item, index) {
return item.reduce(multiply);
});
return result;
}
var numArr = [1, 3, 5, 9];
// create unique 3 number combination
var combi = create3Combi(numArr); //[[1,3,5],[1,3,9],[1,5,9],[3,5,9]]
// multiply every combination
var multiplyResult = multiplyCombi(combi); //[15,27,45,135];
在你要求排列的标题中,但在你提到的组合体中。这是什么? (我猜组合,因为乘法是可交换的。) – 2010-10-30 23:20:02
@DaveKingsnorth注意:你的数组中有字符串,而不是数字。 – 2010-10-30 23:25:29
对不起,这是组合 – DaveKingsnorth 2010-10-30 23:25:37