能否请您告诉我如何找到总和等于数字的所有子数组 例子
arr[] = [2, 4, 45, 6, 0, 19]
x = 51
Output: [2,4,45]
或
arr[] = [1, 11, 100, 1, 0, 200, 3, 2, 1, 280]
x = 280
Output: [280]
我试图那样,但是没有得到正确的输出
function getSubArray(arr, num) {
var sum = 0,
blank = [];
var bigArr = []
for (var i = 0; i < arr.length; i++) {
sum = arr[i];
if (blank.length === 0) {
blank.push(arr[i]);
}
for (var j = 1; i < arr.length; j++) {
sum += arr[j];
if (sum < num) {
blank.push(arr[j])
} else if (sum > num) {
sum = 0;
blank = [];
break;
} else {
blank.push(arr[j])
bigArr.push(blank);
sum = 0;
blank = [];
}
}
}
return bigArr
}
console.log(getSubArray([1, 3, 6, 11, 1, 5, 4], 4));
此预期输出为
console.log(getSubArray([1, 3, 6, 11, 1, 5,4],4));
output: [1,3]
[4]
预期输出 [[1,3],[4]]是我的预期输出
答案 0 :(得分:5)
您可以迭代数组并获取下一个元素,或者在省略该元素之前不获取任何元素。
function getSubset(array, sum) {
function iter(temp, delta, index) {
if (!delta) result.push(temp);
if (index >= array.length) return;
iter(temp.concat(array[index]), delta - array[index], index + 1);
if (!temp.length) iter(temp, delta, index + 1);
}
var result = [];
iter([], sum, 0);
return result;
}
console.log(getSubset([2, 4, 45, 6, 0, 19], 51)); // [2, 4, 45], [45, 6], [45, 6, 0]
console.log(getSubset([1, 11, 100, 1, 0, 200, 3, 2, 1, 280], 280)); // [280]
console.log(getSubset([1, 3, 6, 11, 1, 5, 4], 4)); // [1, 3], [4]
答案 1 :(得分:2)
这可能不完全是必需的-可能需要进行调整,因为此处的逻辑可能有缺陷。
我已经注释了代码以进行澄清。
var arr = [1, 3, 6, 11, 1, 5,4]; // Define array
var target = 31; // Define target
// filter the numbers higher than target and sort rest ascending
var withinRange = arr.filter(x => x <= target).sort((a, b) => a - b);
if(arr.reduce((a,b) => a + b) < target) // Check if we have enough numbers to make up that number
throw "The max you can get out of your selection is: " + arr.reduce((a,b) => a + b);
// grab the highest number as a starting point and remove it from our array of numbers
var numbers = [withinRange.pop()];
var toFind = target - getSum(); // get remainder to find
for(var i = withinRange.length - 1; i > -1; i--) // iterate from the top
{
if(toFind == withinRange[i]){ // check if number is exactly what we need
numbers.push(withinRange[i]);
break;
}else if(withinRange[i] <= toFind){ // if number is smaller than what we look for
numbers.push(withinRange[i]);
toFind -= withinRange[i];
}
}
function getSum(){ // sum up our found numbers
if(numbers.length == 0) return 0;
return numbers.reduce((a,b) => a + b);
}
console.log([numbers, [target]]); // print numbers as desired output
console.log(target, getSum()) // print the target and our numbers
答案 2 :(得分:1)
这将尝试数组的所有可能排列(一旦达到限制,将停止进一步排列)
function test(arr, num) {
// sorting will improve time as larger values will be eliminated first
arr = arr.sort(function(a, b) {
return b - a;
});
var allLists = [];
var start = Date.now();
helper(0, 0, []);
console.log("Ms elapesed: " + (Date.now() - start));
return allLists || "Not found";
function helper(start, total, list) {
var result = [];
// Using for loop is faster because you can start from desired index without using filter, slice, splice ...
for (var index = start; index < arr.length; index++) {
var item = arr[index];
// If the total is too large the path can be skipped alltogether
if (total + item <= num) {
// Check lists if number was not included
var test = helper(index + 1, total, list.concat(result)); // remove for efficiency
total += item;
result.push(item);
//if (total === num) index = arr.length; add for efficiency
}
}
if (total === num) allLists.push(list.concat(result));
}
}
console.log(test([2, 4, 45, 6, 0, 19], 51)); // [2,4,45] [2,4,45,0] [6,45] [6,45,0]
console.log(test([1, 11, 100, 1, 0, 200, 3, 2, 1, 280], 280)); // [280] [280,0]
如果要提高效率,只需返回结果数组之一,只需注释掉递归调用即可。一旦达到限制,您也可以取消注释退出循环的行(将跳过0)。
答案 3 :(得分:1)
它将给出所有可用的情况。我使用@Nina Scholz的测试用例
const sum = arr => arr.reduce((a,b) => a + b)
function cal(arr, x) {
const rs = []
for (let i = 0; i< arr.length; i++) {
const tmp = []
for (let j=i; j<arr.length; j++ ) {
tmp.push(arr[j])
if(sum(tmp) === x) rs.push([...tmp])
}
}
return rs
}
console.log(cal([1, 11, 100, 1, 0, 200, 3, 2, 1, 280], 280)) // -> [280]
console.log(cal([2, 4, 45, 6, 0, 19], 51)); // -> [2, 4, 45] [45, 6] [45, 6, 0]
console.log(cal([1, 3, 6, 11, 1, 5, 4], 4)); // -> [1,3] [4]
答案 4 :(得分:1)
如果问题在于查找具有给定交叉和的所有子集(而不是子数组),则也称为完美和问题。 https://www.geeksforgeeks.org/perfect-sum-problem-print-subsets-given-sum/
>>> df = pd.read_csv("/Users/SO/Desktop/test.csv",sep=';', decimal=",")
>>> df
KG,
0 267.890
1 458.987
2 125.888
3 1.550
4 2.660
>>>
答案 5 :(得分:0)
解决方案
'use strict';
function print(arr[], i, j) {
let k = 0;
for (k = i; k <= j; k += 1) {
console.log(arr[k]);
}
}
function findSubArrays(arr[], sum) {
let n = arr.length;
let i;
let j;
let sum_so_far;
for (i = 0; i<n; i+= 1) {
sum_so_far = 0;
for (j = i; j < n; j++) {
sum_so_far += arr[j];
if (sum_so_far === sum) {
print(arr, i, j);
}
}
}
}
答案 6 :(得分:0)
我将首先根据预期数组的大小进行循环。
在该循环之后,查找数组的第一部分,该部分应填充与所需数字匹配的位置。
例如,对于x = 4且arr = [5,4,32,8,2,1,2,2,3,4,4] 首先要取4。输出将分别在位置[1,9,10]的[[4],[4],[4],....]上
然后对结果为2个元素[... [2,2],[2,2],[2,2],[1,3] ...](位置4 + 6,位置4 + 7位置6 + 7和位置5 + 8) 此时,您可能需要使用另一个函数进行求和并检查。
现在将对3个元素的总和(如果有)执行相同的操作,依此类推,将max循环设置为原始数组的数量(结果数量可能是数组中所有元素的总和)。
结果示例为[[4],[4],[4],[2,2],[2,2],[2,2],[1,3]]
答案 7 :(得分:0)
function combinations(array) {
return new Array(1 << array.length).fill().map(
(e1,i) => array.filter((e2, j) => i & 1 << j));
}
function add(acc,a) {
return acc + a
}
combinations([2, 4, 45, 6, 0, 19]).filter( subarray => subarray.reduce(add, 0) == 51 )
输出
[[2,4,45],[45,6],[2,4,45,0],[45,6,0]]
combinations([1, 11, 100, 1, 0, 200, 3, 2, 1, 280]).filter( subarray => subarray.reduce(add, 0) == 280 )
输出
[[280],[0,280]]
答案 8 :(得分:0)
如果这些元素严格意义上是正的,则可以一次收集此类子序列,并以蠕虫/毛虫的方式前进:伸展其前端以增加总和(当它是目标以下时)并收缩其后部以降低总和:
function worm(arr,target){
var ret=[];
var head=0;
var tail=0;
var sum=0;
while(head<arr.length){
while(sum<=target && head<arr.length){
sum+=arr[head++];
if(sum===target)
ret.push(arr.slice(tail,head));
}
while(sum>=target && tail<head){
sum-=arr[tail++];
if(sum===target)
ret.push(arr.slice(tail,head));
}
}
return JSON.stringify(arr)+": "+JSON.stringify(ret);
}
console.log(worm([2, 4, 45, 6, 19], 51));
console.log(worm([1, 11, 100, 1, 200, 3, 2, 1, 280], 280));
console.log(worm([1, 3, 6, 11, 1, 5, 4], 4));
console.log("But it only occasionally finds 0+... / ...+0 sums:");
console.log(worm([2, 4, 45, 6, 0, 19], 51));
console.log(worm([2, 4, 0, 45, 0, 6, 0, 19], 51));
console.log(worm([0, 2, 4, 0, 45, 0, 6, 0, 19], 51));
处理与边界零相关的问题的一种方法是丢弃此类序列。此代码段将tail
和head(-1)
保留在非零元素上:
function worm(arr,target){
var ret=[];
var head=0;
while(head<arr.length && arr[head]===0)head++;
var tail=head;
var sum=0;
while(head<arr.length){
while(sum<=target && head<arr.length){
while(head<arr.length && arr[head]===0)head++;
sum+=arr[head++];
if(sum===target)
ret.push(arr.slice(tail,head));
}
while(sum>=target && tail<head){
sum-=arr[tail++];
while(tail<head && arr[tail]===0)tail++;
if(sum===target)
ret.push(arr.slice(tail,head));
}
}
return JSON.stringify(arr)+": "+JSON.stringify(ret);
}
console.log(worm([2, 4, 45, 6, 19], 51));
console.log(worm([1, 11, 100, 1, 200, 3, 2, 1, 280], 280));
console.log(worm([1, 3, 6, 11, 1, 5, 4], 4));
console.log(worm([2, 4, 45, 6, 0, 19], 51));
console.log(worm([2, 4, 0, 45, 0, 6, 0, 19], 51));
console.log(worm([0, 2, 4, 0, 45, 0, 6, 0, 19], 51));
console.log(worm([0, 2, 4, 0, 45, 0, 6, 0, 19, 26], 51));
console.log(worm([0, 2, 4, 0, 45, 0, 6, 0, 19, 26, 0], 51));
console.log(worm([1,8,2], 10));
console.log(worm([0,1,0,8,2,0], 10));
console.log(worm([0,8,2,8,0], 10));
console.log(worm([0,8,0,2,0,8,0], 10));
如果某人实际上需要这些0+...
/ ...+0
序列,那么代码将失去所有剩余的美感,因为它们必须在后期处理步骤中生成:
function worm(arr,target){
var pairs=[];
var head=0;
while(head<arr.length && arr[head]===0)head++;
var tail=head;
var sum=0;
while(head<arr.length){
while(sum<=target && head<arr.length){
while(head<arr.length && arr[head]===0)head++;
sum+=arr[head++];
if(sum===target)
pairs.push([tail,head]);
}
while(sum>=target && tail<head){
sum-=arr[tail++];
while(tail<head && arr[tail]===0)tail++;
if(sum===target)
pairs.push([tail,head]);
}
}
var ret=[];
for([tail,head] of pairs){
(function pre(tail,head){
ret.push(arr.slice(tail,head));
if(tail>0 && arr[tail-1]===0)
pre(tail-1,head);
(function post(tail,head){
if(head<arr.length && arr[head]===0){
ret.push(arr.slice(tail,head+1));
post(tail,head+1);
}
})(tail,head);
})(tail,head);
}
return JSON.stringify(arr)+": "+JSON.stringify(ret);
}
console.log(worm([2, 4, 45, 6, 19], 51));
console.log(worm([1, 11, 100, 1, 200, 3, 2, 1, 280], 280));
console.log(worm([1, 3, 6, 11, 1, 5, 4], 4));
console.log(worm([2, 4, 45, 6, 0, 19], 51));
console.log(worm([2, 4, 0, 45, 0, 6, 0, 19], 51));
console.log(worm([0, 2, 4, 0, 45, 0, 6, 0, 19], 51));
console.log(worm([0, 2, 4, 0, 45, 0, 6, 0, 19, 26], 51));
console.log(worm([0, 2, 4, 0, 45, 0, 6, 0, 19, 26, 0], 51));
console.log(worm([1,8,2], 10));
console.log(worm([0,1,0,8,2,0], 10));
console.log(worm([0,8,2,8,0], 10));
console.log(worm([0,8,0,2,0,8,0], 10));
我认为它适用于(非负元素),但是第一个肯定更简单。