我创建了一个计算整数位数之和的函数。为了缩短代码,我在if语句中添加注释以查看它是否仍然有用,所以我可以将其删除但是我得到了StackOverflowError
,为什么?
这是我的代码:
public static int sumDigits(int n) {
//if(n%10==n){ return n;}
return n%10+sumDigits(n/10);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(sumDigits(12611));
}
答案 0 :(得分:4)
它永远不会回归,但只是更深入和更深入地进行。
你有一个return语句,但在返回之前需要计算表达式n%10+sumDigits(n/10)
的值,这涉及无限递归。
注意:每次从自身调用函数时,函数的上下文(局部变量)都会添加到堆栈顶部。堆栈的大小有限。最终达到该大小,StackOverflowError是在这种情况下抛出的错误。
答案 1 :(得分:3)
那是因为没有停止条款。您将永远调用sumDigits
。
答案 2 :(得分:3)
递归函数可以定义为在靠近终点的值上将操作表示为该操作的函数。
因此,每个递归函数在某个时刻都需要一个结束条件,否则将无限地重复(或者更准确地说,直到你的堆栈为止)。
“数字之和”递归方法的基本定义(对于n
的非负值)是:
def sumOfDigits (n):
if n < 10:
return n
return (n % 10) + sumOfDigits (n / 10) # assumes integer division.
第一点,结束条件非常重要,你似乎因某种原因对你进行了评论。
答案 3 :(得分:2)
如果删除该行,则recursion不再有基本案例,这意味着它永远不会返回。
答案 4 :(得分:2)
因此,当您递归调用sumDigits()
时,系统会继续以LIFO方式保存最后一次跟踪。这样系统就可以很容易地返回到先前的地址,这对于递归是必须的。
如果无限地或高于内存约束进行递归,则会遇到stackOverflow错误。
答案 5 :(得分:2)
您注释掉的语句是此递归函数的基本案例。没有基本情况,这个函数将无限循环。
当您在main方法中计算出示例时,您会得到:
sumDigits(12611)
= 1 + sumDigits(1261)
= 1 +(1 + sumDigits(126))
= 1 +(1 +(6 + sumDigits(12)))
= 1 +(1 +(6 +(2 + sumDigits(1))))
= 1 +(1 +(6 +(2 +(1 + sumDigits(0)))))//此时注释掉的if语句将返回
= 1 +(1 +(6 +(2 +(1 +(0 + sumDigits(0))))))
= 1 +(1 +(6 +(2 +(1 +(0 +(0 + sumDigits(0)))))))
...
此时程序陷入无限循环。当n为1时,注释掉的语句将返回,从而防止出现这种情况。
答案 6 :(得分:1)
因为你从它自己调用sumDigits()
并且注释掉应该导致你从无限递归返回的代码。取消注释行if(n%10==n){ return n;}
答案 7 :(得分:1)
您的递归没有终止条件。否则,你一遍又一遍地调用递归函数,最终stack
将溢出
答案 8 :(得分:0)
取消注释您的停止条件。