列出1、2和3相加为4的所有方式,顺序很重要。例如,[1,1,1,1]
是一种方法<代码>[1,1,2]与[1,2,1]
不同
我已经想出了一个理论上可行的方法。但是我仍然不能为它写代码。请帮助,请检查我的想法清晰的图片。
我写的这个代码失败了。但这就是我已经走了多远。
function theseAddToSum(steps = [], sum) {
let results = [];
if (steps.length < 1) return 'error'
for (let i = 0; i < steps.length; i++) {
let cur = steps[i];
let remaining = sum - cur;
if (remaining >= 0) {
console.log('sum', sum, 'step', cur)
let c = theseAddToSum(steps, remaining)
}
}
return results
}
console.log(theseAddToSum([1, 2, 3], 4))
当我console.log('sum', sum,'Step', cur)
时,我得到了想要的结果:
sum 4 step 1
sum 3 step 1
sum 2 step 1
sum 1 step 1
sum 2 step 2
sum 3 step 2
sum 1 step 1
sum 3 step 3
sum 4 step 2
sum 2 step 1
sum 1 step 1
sum 2 step 2
sum 4 step 3
sum 1 step 1
我的问题是,我不知道如何将结果推送到结果
数组。它应该看起来像[[1,1,1,1]、[1,2,2]、[2,1]、[1,3]、[3,1,2]等等]
这是使用回溯的绝佳机会。回溯的想法是,我们开始尝试所有可能的组合,但当我们当前的组合失败了,我们不能继续在它的基础上建立,然后我们回去尝试别的东西。
我们处理回溯问题的方式如下:
话真多,我们来解决问题:
const getSum = (arr) => arr.reduce((acc, num) => num + acc, 0);
function theseAddToSum(steps, sum) {
const solutions = [];
function recurse(steps, sum, currentSol) {
if (getSum(currentSol) === sum) {
solutions.push([...currentSol]);
return
}
for (let i = 0; i < steps.length; i++) {
currentSol.push(steps[i]);
if (getSum(currentSol) <= sum) {
recurse(steps, sum, currentSol);
}
currentSol.pop();
}
}
recurse(steps, sum, [])
return solutions;
}
console.log(theseAddToSum([1, 2, 3], 4));
一些问题:
>
尽管递归调用返回的数组被捕获在变量c
中,但该变量没有进一步使用,因此它一直没有用。
结果
被初始化为[]
,但随后从未被修改/扩展,因此最终的返回结果
保证返回该空列表。
以上两个问题需要通过迭代< code>c中的解决方案来解决:将当前值追加到那些解决方案中(因为我们已经减去了那个值以获得那些解决方案),并将那些扩展的解决方案追加到当前的< code>results数组中。
当< code>remaining等于0时,进行更多的递归调用是没有意义的。这实际上是递归的一个基本情况。(我更喜欢在递归的更深一层,在函数的开始进行这种检查:如果和是0,我们应该返回一个空解,然后当我们从递归中返回时,可以用选择的值扩展这个空解)。
无关,但最好用分号分隔你的语句。你不会是第一个落入自动分号插入陷阱的人。最好掌握控制权。
以下是更正后的版本:
js lang-js prettyprint-override">function theseAddToSum(steps = [], sum) {
// Base cases:
if (sum < 0) return []; // No solutions
if (sum == 0) return [[]]; // A solution
let results = [];
if (steps.length < 1) return 'error';
for (let i = 0; i < steps.length; i++) {
let cur = steps[i];
let remaining = sum - cur;
let c = theseAddToSum(steps, remaining)
// Use the solutions we got back from recursion
for (let solution of c) {
solution.push(cur); // ... then extend them
results.push(solution); // ... and collect them
}
}
return results;
}
console.log(theseAddToSum([1, 2, 3], 4));
问题内容: 我正在尝试将长度不定的多个数据列表输出到CSV文件。每个列表应该是输出CSV文件中的一列。有直接的做事方法吗?如果我将每个列表输出为一行,那么我将遍历每个列表并在结束时输出返回值,但是这种方法在按列工作时不起作用。 我曾想过一次逐项检查所有列表并增加一个计数器,但这也会失败,因为有些列表比另一些更长。为了解决这个问题,我将不得不在每次迭代时检查计数器是否在每个列表的末尾,这在计算方
本文向大家介绍求以下表达式的值,写出您想到的一种或几种实现方法:1-2+3-4+……+m相关面试题,主要包含被问及求以下表达式的值,写出您想到的一种或几种实现方法:1-2+3-4+……+m时的应答技巧和注意事项,需要的朋友参考一下 答:
前端哪种加密方式是 8-4-4-4-12 的格式? 图片传参需要转换为 8-4-4-4-12 格式(8位数字+字母组合 - 4位数字+字母组合……),中间横杠连接,有佬了解这种加密方式吗
本文向大家介绍动态加载JavaScript文件的3种方式,包括了动态加载JavaScript文件的3种方式的使用技巧和注意事项,需要的朋友参考一下 以下是遇到的几种动态加载JavaScript文件的方式,持续更新中。。。 一、使用document.write/writeln()方式 该种方式可以实现js文件的动态加载,原理就是在重写文档流,这种方式会导致整个页面重绘。 实现方式: 需要注意的是特殊
本文向大家介绍js实现类似于add(1)(2)(3)调用方式的方法,包括了js实现类似于add(1)(2)(3)调用方式的方法的使用技巧和注意事项,需要的朋友参考一下 没错!那要是add(1)(2)(3)(4) 这样4个调用呢,那这个肯定不适用了。 这种就是类似于执行一个函数返回函数自身值: 但是在计算完成后还是返回了tmp这个函数,这样就获取不到计算的结果了,我们需要的结果是一个计算的数字那么怎
对于这个公式 我必须制定一个方法来自动化它,我已经收到了4个例子来尝试它。 x=1 x=3 x = 4 然而,当我插入11时,答案应该是3.0198773447,我收到的是-1.78316945E8:/ 这是我的代码: