Javascript 存储桶之间的所有项目分布

Javascript 存储桶之间的所有项目分布,javascript,arrays,algorithm,Javascript,Arrays,Algorithm,我最近遇到了一个问题,我需要找出如何将项目分配到存储桶中,但我需要找到所有分配它们的方法 输入是一个整数数组,它告诉您每列可以容纳的最大值,并且数组中必须有N个项目 例如: maxItems = 3 maximums = [4,2,1] # The order of maximums DOES matter meaning # This means that the results of maximums = [2,4,1] are different from maximums = [1,2,

我最近遇到了一个问题,我需要找出如何将项目分配到存储桶中,但我需要找到所有分配它们的方法

输入是一个整数数组,它告诉您每列可以容纳的最大值,并且数组中必须有N个项目

例如:

maxItems = 3
maximums = [4,2,1] # The order of maximums DOES matter meaning
# This means that the results of maximums = [2,4,1] are different from maximums = [1,2,4]
outputs = [[3,0,0],[2,1,0],[1,1,1],[2,0,1],[0,2,1]] # results are in no particular order
# notice how the sum of each result is equal to maxItems and each value in each of the rows are less than the value inside of maximums
我试图用javascript解决这个问题,但我不知道如何解决这个问题。我想先用尽可能多的数字填充第一列,然后开始向右移动,但随着最大值数组变大,这种方法变得更不准确,我根本不知道如何处理它

如果您还有任何问题,请随时提问,如果您不理解这个问题

我在javascript中开始使用的代码是

var all_combinations = function(N, maximums){
    var empty = maximums.map(function(){return 0;}); // create empty array size of maximums filled with 0s
    var s = 0;
    for (var i = 0; i < empty.length && s < N;){
        if (empty[i] >= maximums[i]){i++;continue;}
        empty[i]++;
        s++;
    } // fill the left side with as many items as possible

    // Then i would proceed to move one item at a time to the right side but some how i would need to do it for the whole array and this is where I get stuck.
};
var all_组合=函数(N,最大值){
var empty=maximums.map(function(){return 0;});//创建用0填充的最大值的空数组大小
var s=0;
对于(变量i=0;i=最大值[i]){i++;继续;}
空[i]++;
s++;
}//在左侧填充尽可能多的项目
//然后我会继续一次移动一个项目到右侧,但是我需要如何为整个阵列移动,这就是我被卡住的地方。
};
我试图寻找这个问题,但我从来没有发现如何做它的方式设置在这里。我试图找到类似的问题,但它们总是与此无关。也许我找错问题了。如果有人能链接一个有用的资源,那就太好了


如果你有任何问题,请问他们。我将尽我所能回答。

您可以使用递归方法检查约束的所有部分

它使用一个索引和一个临时数组来保持项目的计数

开始时,索引为零,数组为空。通过调用
fork
,第一个退出选项被选中,这意味着约束被选中,如果计数大于或等于,则递归停止

第二个退出选项是当项目总数达到所需计数时,临时数组被推送到结果集,递归结束

在所有其他情况下,
fork
将使用以下任一选项再次调用

  • 相同的索引
    i
    和索引处临时数组的增量值,或
  • 递增的索引和实际的临时数组
函数getCombination(最大值,计数){ 功能叉(索引、温度){ var总和=温度降低((a,b)=>a+b,0); 如果(max.some((a,i)=>(temp[i]| 0)>a)|索引===max.length | sum>count){ 返回; } 如果(总和==计数){ 结果:推送(温度); 返回; } fork(索引,max.map((a,i)=>(temp[i]| 0)+(i==索引)); 叉(指数+1,温度); } var结果=[]; fork(0,[]); 返回结果; } log(getcomposition([4,2,1,3])
.as控制台包装{max height:100%!important;top:0;}
一个易于理解的ECMA 6生成器递归解决方案:

对于每个
i
,如果合适,将
i
项目放入第一个插槽,然后将其他项目分配给其他项目

函数*bucket_分布(容量、单位){
如果(容量.长度==1){
if(容量[0]>=nItems)
产量[硝态氮];
}
否则如果(容量.长度>1){
对于(var i=Math.min(容量[0],nItems);i>=0;i--){
for(的子列表)
桶分布(容量切片(1),nItems-i))
收益率[i].混凝土(子标);
}
}
}

console.log(Array.from(bucket_分布([4,2,1],3))
下面是一个评论良好的迭代解决方案,带有一个交互式演示:

//用于计算数组和的reducer函数
函数和(上一个,下一个){
返回上一个+下一个;
}
//返回存储桶的上下文约束
函数bucketMinMax(maxItems、otherItems、bucketMax){
返回{
//满足maxItems的桶中的最小值
最小值:Math.max(0,maxItems-otherItems),
//满足maxItems的桶中的最大值
最大值:数学最小值(maxItems,bucketMax),
};
}
//获取一个不完整的组合并用下一个bucket展开它
//从左边开始
函数组合(最大项、最大值、组合){
//获取要展开的下一个组合组
var comboGroup=combions.shift();
//获取膨胀桶的索引
var指数=comboGroup.length;
//计算最大可能的其他项目
var otherItems=最大值。切片(索引+1)。减少(总和,0);
//从要展开的组合组中的maxItems中删除已使用的空格
maxItems-=comboGroup.reduce(总和,0);
//获取扩展桶的约束
var{min,max}=bucketMinMax(最大项,其他项,最大值[索引]);
对于(变量i=min;i 0&&output[0]。长度<最大值。长度){
//获取不完整的组合组并用可能的值展开它
//用于从左侧开始的下一个铲斗
扩展组合(最大项、最大值、输出);
}
返回输出;
}
document.addEventListener('change',()=>{
var maxes=JSON.parse(maximums.value);
var items=JSON.parse(maxItems.value);
log(JSON.stringify(所有组合(项、最大值));
});
文件。调度事件(新事件(“变更”)
maxItems
最大值

我是否遗漏了一些信息以使这成为一个可接受的问题?已经进行了一次接近票数的投票,而且还不到5分钟不,你没有。我个人不同意投票结束这项工作,只是这是一个有点计算机科学重的问题,关于SO的大多数问题都是简单的“请帮助修复我的程序”之类的交易,所以回答这个问题需要更长的时间。不过别担心,你来对地方了,我