我想找到一种方法,在数组中合并四个百分比之间的所有可能性。
想要的结果:
possibilities = [[100,0,0,0],[99,1,0,0],[99,0,1,0],...,[0,0,1,99],[0,0,0,100]]
我使用此功能但速度很慢,似乎无法产生所有可能性。
combinePossibilities : function(a, min, max) {
var deferred = $q.defer();
function toObject(arr) {
var rv = {};
for (var i = 0; i < arr.length; ++i){
rv['fund'+i] = arr[i];
}
return rv;
}
var fn = function(n, src, got, all) {
if (n === 0) {
if (got.length > 0) {
var total = 0;
angular.forEach(got, function(value){
total += value; //GET TOTAL OF THE COMBINATION
});
if(total === 100){
all.push(toObject(got));
}
}
return;
}
for (var j = 0; j < src.length; j++) {
fn(n - 1, src.slice(j + 1), got.concat([src[j]]), all);
}
return;
};
var all = [];
for (var i = min; i <= max; i++) {
console.log(a);
fn(i, a, [], all);
}
deferred.resolve(all);
return deferred.promise;
}
我在这里找到了这个函数Find all possible subset combos in an array?并将其修改为只接受我的数组结果等于100%。
有任何线索吗?
谢谢。
答案 0 :(得分:2)
这个提议是一个函数递归函数,它取总和和长度。它返回一个数组,其中包含从总和到零的组合值的数组。
function combine(sum, length, part) {
var result = [],
i = sum;
part = part || [];
if (length === 1) {
return [part.concat(sum)];
}
if (length === 0) {
return [part];
}
do {
result = result.concat(combine(sum - i, length - 1, part.concat(i)));
} while (i--);
return result;
}
工作原理:
它以给定的
sum
和length
以及空的result
集合开头,以及值为i
的迭代器变量sum
。如果未给出
part
,则分配一个空数组。现在进行一些检查(剩余的)
length
及其特殊处理,如果是
1
:这是最后一次迭代,只留下sum
。然后返回数组中由part
连接的部分结果sum
。
0
:不再迭代,然后在数组中返回部分结果part
。如果
length
既不是1
也不是0
,那么将sum
上的内容整合为零。
combine
的来电将减少的sum
,减少的length
和部分结果part
的值i
。
combine()
的通话结果会与result
套装连接。
combine(5, 3)
的示例:length: 21 [ [5, 0, 0], [4, 1, 0], [4, 0, 1], [3, 2, 0], [3, 1, 1], [3, 0, 2], [2, 3, 0], [2, 2, 1], [2, 1, 2], [2, 0, 3], [1, 4, 0], [1, 3, 1], [1, 2, 2], [1, 1, 3], [1, 0, 4], [0, 5, 0], [0, 4, 1], [0, 3, 2], [0, 2, 3], [0, 1, 4], [0, 0, 5] ]
包含两个示例的工作代码:
combine(5, 3)
combine(10, 4)
function combine(sum, length, part) {
var result = [],
i = sum;
part = part || [];
if (length === 1) {
return [part.concat(sum)];
}
if (length === 0) {
return [part];
}
do {
result = result.concat(combine(sum - i, length - 1, part.concat(i)));
} while (i--);
return result;
}
function print(array) {
document.write('<pre>length: ' + array.length + '\n' + JSON.stringify(array, 0, 4) + '</pre>');
}
print(combine(5, 3));
print(combine(10, 4));