我正在学习JavaScript的基础知识,并试图编写一个递归函数来将一组整数加在一起。例如,函数参数为1234
,结果应为10
。这就是我到目前为止所拥有的......
function sumDigits(numbersStr) {
var numToString = numbersStr.toString()
var numArr = numToString.split('').map(Number);
var sum = 0;
// base case
if (numArr.length === 0) {
return sum
}
// recursive case
else {
var popped = numArr.pop();
sum+=popped;
return sumDigits(numArr);
}
}
但每当我运行它时,我会得到一个无限循环(我的标签崩溃)。如果我弹出数组的最后一个元素,将其添加到sum
变量,然后在缩短的数组上再次调用该函数,那为什么我会得到一个无限循环?非常感谢!
答案 0 :(得分:3)
你的代码中的问题是sumDigits期望得到一个数字,但在递归中你传递一个数字数组。
答案 1 :(得分:2)
您可以使用字符串或数字作为函数的参数,并将值转换为字符串。
然后检查长度并在长度为零时返回零(通常是退出条件)。
如果不返回第一个字符的值,则使用索引1中的切片字符串添加调用函数的结果。
基本上,recurisve函数有两个部分。
具有退出值的退出条件。这取决于递归函数的目的。它通常是一个中性值,如加法为零,或乘法为1
。
执行值表示算术运算,再次使用减少的字符串/数组或数值调用函数。
function sumDigits(num) {
num = num.toString();
return num.length === 0
? 0
: +num[0] + sumDigits(num.slice(1));
}
console.log(sumDigits(1234));
另一种方法是使用tail recursion,它不会为每个调用函数扩展堆栈,因为函数以调用结束,而不保留上面函数中的临时值,实际数值{{ 1}}和等待执行adition。
在这种情况下,您可以存储中间结果以及调用函数。
+num[0]
答案 2 :(得分:1)
function digitCount(num) {
let val1 = num % 10
let rem = Math.floor(num / 10)
return val1 + (rem != 0 ? digitCount(rem) : 0)
}
console.log(digitCount(87))
答案 3 :(得分:0)
问题是你的函数接受一个数字作为它的参数,但是当你递归地使用它时,你会给它一个数组。我建议将递归部分拉入自己的辅助函数,如下所示:
public class Parent
{
[Key]
public Guid Id { get; set; }
public virtual ICollection<Child> Children { get; set; }
}
public class Child
{
[Key]
public Guid Id { get; set; }
public Guid ParentId { get; set; }
[ForeignKey("ParentId")]
public virtual Parent Parent { get; set; }
}
答案 4 :(得分:0)
你的函数需要一个字符串,但在递归调用中,你传递一个数组。
此外,您已拨打.map
不需要的电话,因为您可以将.split
数组中的字符串转换为数字,只需预先设置+
对他们来说。
你有什么理由不使用Array.reduce
吗?
function sumDigits(stringOfNums) {
// Split the string into an array of strings. Reduce the array to the sum by
// converting each string to a number.
console.log(stringOfNums.split('').reduce(function(x,y){ return +x + +y}, 0));
}
sumDigits("1234");
&#13;
答案 5 :(得分:0)
在递归调用中传递数组将保证其.toString()
永远不会为空,因为逗号将添加的字符数多于已删除的字符数。
相反,请以数学方式进行,这样您就不需要数组甚至字符串转换。
function sumDigits(num) {
return num ? (num%10) + sumDigits(Math.floor(num/10)) : 0
}
console.log(sumDigits(1234))
这假设传递了一个正整数。如果可以提供其他输入,您将需要额外的警卫。
答案 6 :(得分:0)
无需将数字转换为数组。您可以使用0
获取数字的最后一位数字,并使用number % 10
删除该数字。然后递归,直到数字为Math.floor(number / 10)
。
0
答案 7 :(得分:0)
String.prototype.split
这样的高级功能可能不会教你很多。
这是一个使用功能风格编写的尾递归版Barmar程序
n
为零,返回累加器acc
n
不零;重复使用下一个n
和下一个acc
const sumDigits = (n = 0, acc = 0) =>
n === 0
? acc
: sumDigits (n / 10 >> 0, acc + n % 10)
console.log (sumDigits ()) // 0
console.log (sumDigits (1)) // 1
console.log (sumDigits (12)) // 3
console.log (sumDigits (123)) // 6
console.log (sumDigits (1234)) // 10
&#13;