假设某个编程语言不支持函数调用本身,如何实现递归

举个例子,使用常见的语言,任何人都能毫不费力地写出一个阶乘函数。下面用JavaScript举例:

function factorial(n) {
    if (n === 1) return 1;
    return n * factorial(n-1); // 调用了本身
}

factorial(4); // 24

但是,一个有意思的思考是,假设当前语言不支持函数调用自身,我们应该如何实现这种递归?

方式1

以下js代码可以直接运行,并且其中没有使用js的递归能力。

function _factorial(self, n) {
    if (n === 1) return 1;
    return n * self(self, n-1);
}

function factorial(n) {
    return _factorial(_factorial, n);
}

factorial(4); // 24

思路是,虽然函数不能直接引用自己,但是可以使用参数!如果调用者把_factorial作为参数传递给_factorial,那么_factorial就能通过参数拿到“自己”。

这个思路可以用来实现任何递归函数。

方式2:YCombinator

以下js代码可以直接运行,并且其中没有使用js的递归能力。

const _factorial = (getSelf) => (n) => {
    if (n === 1) return 1;
    return n * getSelf()(n-1);
}

function YCombinator(F) {
   const f_gen = (self) => F(() => self(self));
   return f_gen(f_gen);
}

const factorial = YCombinator(_factorial);

factorial(4); // 24

YCombinator是通用的,可以求解任何高阶函数的不动点。YCombinator可以帮助我们在不支持递归的语言中实现递归。比如,斐波那契数的计算:

const _fib = (getSelf) => (n) => {
    if (n === 0 || n === 1) return n;
    const self = getSelf();
    return self(n-1) + self(n-2);
}

function YCombinator(F) {
   const f_gen = (self) => F(() => self(self));
   return f_gen(f_gen);
}

const fib = YCombinator(_fib);

// 斐波那契数列:0 1 1 2 3 5 8
fib(6); // 8
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值