问题:
递归: n! =123*(n-1)*n;
3!
每一次递归 栈都会分配内存,如果次数太多 栈的内存不够了 就会报错.
解决方法
-
扩大栈 的容量 修改Xss
但不是长久之计 -
c 语言 –尾调用 最后一次 在执行运算 阻止递归一次就分配一次内存
-
java如何?在这里插入图片描述
实现
首先我们实现了一个尾调用的接口,方便大家使用:
// 尾调用的接口,定义了是否完成,执行等方法
public interface TailRecursion<T> {
TailRecursion<T> apply();
default Boolean isComplete() { return Boolean.FALSE; }
default T getResult() {
throw new RuntimeException("递归还没有结束,暂时得不到结果"); }
default T invoke() {
return Stream.iterate(this,
TailRecursion::apply)
.filter(TailRecursion::isComplete)
.findFirst()
.get()//执行急方法
.getResult(); } }
//接着实现了利用这个接口实现 9k 的阶乘,代码如下:
public class TestDTO {
private Long begin;
private Long end;
private BigDecimal total;
}
public static TailRecursion<BigDecimal> recursion1(TestDTO testDTO{
// 如果已经递归到最后一个数字了,结束递归,返回 testDTO.getTotal() 值
if (testDTO.getBegin().equals(testDTO.getEnd())) {
return TailRecursionCall.done(testDTO.getTotal()); }
testDTO.setBegin(1+testDTO.getBegin()); // 计算本次递归的值
testDTO.setTotal(testDTO
.getTotal().multiply(new BigDecimal(testDTO.getBegin())));
// 这里是最大的不同,这里每次调用递归 方法时,使用的是 Lambda 的方式,这
//样只是初始化了一个 Lambda 变量而已,recursion1 方法的内存是不会分配的
return TailRecursionCall.call(()->recursion1(testDTO)); }
最后我们写了一个测试方法,我们把栈的大小设定成 200k,测试代码如下:
public void testRecursion1(){
TestDTO testDTO = new TestDTO(); testDTO.setBegin(1L);
testDTO.setEnd(9000L); testDTO.setTotal(BigDecimal.ONE);
log.info("计算 9k 的阶乘,结果为{}",recursion1(testDTO).invoke()); }