我有一个函数(from Akseli Palén)来计算给定数组中X元素的组合,看起来像这样。
function k_combinations(set, k) {
var i, j, combs, head, tailcombs;
if (k > set.length || k <= 0) { return []; }
if (k == set.length) { return [set]; }
if (k == 1) {
combs = [];
for (i = 0; i < set.length; i++) { combs.push([set[i]]); }
return combs;
}
// Assert {1 < k < set.length}
combs = [];
for (i = 0; i < set.length - k + 1; i++) {
head = set.slice(i, i+1);
tailcombs = k_combinations(set.slice(i + 1), k - 1);
for (j = 0; j < tailcombs.length; j++) {
combs.push(head.concat(tailcombs[j]));
}
}
return combs;
}
它工作得很好,但是当给出一个大的数组和/或K值来使用它时,它会减慢到浏览器试图阻止脚本无响应的程度,所以我想知道是否有可能扩展这个函数,它接受一个调用中返回的起始位置和最大结果数?这样我可以做一些像“显示结果20-30万分之一”。有一个样本表格 http://jsbin.com/ricabomofetu/1/edit?js,output如果有人想要破解那么。
答案 0 :(得分:0)
这样的事情怎么样?
function k_combinations(set, k, start_combo, max_results) {
if (start_combo.length !== k)
throw new Error("Starting combination is not of length k!");
var cur = [];
for (var i = 0; i < k; i++) {
var idx = set.indexOf(start_combo[i]);
if (idx === -1)
throw new Error(i + "th element of starting combination isn't in the set!");
if (i > 0 && idx <= cur[i - 1])
throw new Error("Elements of start_combo must be in sorted order!");
cur.push(idx);
}
function subset_from_indices(subset) {
var ret = [];
for (var i = 0; i < subset.length; i++)
ret.push(set[subset[i]]);
return ret;
}
var n = set.length;
var results = [subset_from_indices(cur)];
while (results.length < max_results) {
var inc_idx = k - 1;
while (inc_idx >= 0 && cur[inc_idx] === n - k + inc_idx)
inc_idx--;
if (inc_idx < 0) // no more combinations
return results
cur[inc_idx]++;
for (var i = inc_idx + 1; i < k; i++) {
cur[i] = cur[i - 1] + 1;
}
results.push(subset_from_indices(cur));
}
return results;
}
console.log(k_combinations([1, 2, 3, 4, 5], 3, [1, 3, 4], 4));
// [ [ 1, 3, 4 ], [ 1, 3, 5 ], [ 1, 4, 5 ], [ 2, 3, 4 ] ]