调试可能的和数-JavaScript
我正在编写一个算法,从包含唯一值的数组和包含第一个数组中每个对应值的数量的第二个数组中查找可能的和的数量。例如,对调试可能的和数-JavaScript,javascript,algorithm,debugging,set,subset,Javascript,Algorithm,Debugging,Set,Subset,我正在编写一个算法,从包含唯一值的数组和包含第一个数组中每个对应值的数量的第二个数组中查找可能的和的数量。例如,对[10,20,50]和[1,2,1]表示我正在组合的元素总数实际上是[10,20,20,50],因为数字20有两个实例 我的算法目前通过了除一个测试之外的所有测试,我一辈子都不知道为什么,因为它通过了其他更复杂的配对。以下是我目前的算法: function possibleSums(values, quantity) { const sums = new Set([]);
[10,20,50]和[1,2,1]
表示我正在组合的元素总数实际上是[10,20,20,50]
,因为数字20有两个实例
我的算法目前通过了除一个测试之外的所有测试,我一辈子都不知道为什么,因为它通过了其他更复杂的配对。以下是我目前的算法:
function possibleSums(values, quantity) {
const sums = new Set([]);
//my recursive function that finds all possible combinations moving
//down from a specific starting index in the valueArrray:
const combinations = (valueArray, countArray, position, currentSum) => {
if (currentSum > 0) sums.add(currentSum);
for(let i = position; i < valueArray.length; i++){
if (countArray[i] === 0){
continue;
}
currentSum += valueArray[i];
//reduce the count of that value that is still available
countArray[i]--;
//send off a recursive call to find the sum with the next
//available value
combinations(valueArray, countArray, i, currentSum);
//return the original count since `i` is increasing past
//the current value's location in the valueArray
countArray[i]++;
}
}
for (let i = 0; i < values.length; i++){
//start the recursive function calls at each index in the value array
combinations(values, quantity, i, 0)
}
return sums.size
}
函数可能性(值、数量){
常量和=新集合([]);
//我的递归函数,用于查找所有可能的移动组合
//从ValueArray中的特定起始索引向下:
常量组合=(valueArray、countArray、position、currentSum)=>{
如果(currentSum>0)求和,则添加(currentSum);
for(设i=position;i
此算法传递数组对,如下所示:
[3,1,1]和[111,84,104]
,预期输出为521
[1,1,1,1,1]和[9,19,18,12,19]
的预期输出为77
[1,2,3]和[2,3,10000]
,预期输出30008
但是失败了吗
[10,50,100,500]和[5,3,2,2]
,当预期输出为122时,输出96
有人能发现我的逻辑中缺少了什么吗?122预期输出不是太大,这是一个日志记录的测试用例:) 让我们记录参数:
。。。
常量组合=(valueArray、countArray、position、currentSum)=>{
console.log(countArray、position、currentSum)
如果(当前和。。。
我们看到了这一点,这是有道理的:
[ 0, 0, 0, 0 ] 3 1400
但我们也看到:
[ 0, 0, 1, 0 ] 3 1400
[ 0, 1, 0, 0 ] 3 1400
...
[ 1, 1, 1, 0 ] 3 1400
但事实并非如此
在迭代期间更改当前参数似乎会影响其他调用期间的变量
改变
currentSum+=valueArray[i];
...
组合(valueArray、countArray、i、currentSum);
到
//currentSum+=valueArray[i];
...
组合(valueArray、countArray、i、currentSum+valueArray[i]);
似乎就是这样。你已经尝试过哪种类型的调试?我对输入如何产生输出感到困惑。例如,
[3,1,1]和[111,84104]
。如果你做了3*111+1*84+1*104,你会得到521,这是你所期望的。然而,[5,3,2,2]和[10,50,100,500]
你说应该是122?你能提供更多的测试用例吗?@mhodges第一个数组是值…就像货币的面额一样,第二个数组是每个值的数量,所以对于这对[3,1,1]和[111,84104]
有111个值3,84个值1,还有104个值1…在测试用例中,我无法通过[10,50100500]
和[5,3,2,2]
,有5个值为10,3个值为50,依此类推。在可能的子集内有重复的总和(即[10,10,10,10,10]
=50,[50]
=50,等等),所以我只想返回所有可能子集的唯一和的总数,而不仅仅是排列的数目。@Veehmot更多的测试用例是[10,50,100]和[1,2,1]
正确返回9,[1,2,3]和[2,3,10000]
正确返回30008和[1,1,1,1,1]和[9,19,18,12,19]
,正确返回77。非常感谢。我正在使用MacBook Air,它的小屏幕使更大的控制台日志无法承受,因此我尝试将其缩小。这是一个简单的疏忽,但保护currentSum的值非常有意义。这是一个在中编程时需要牢记的伟大概念未来。