You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

判断DrRacket中给定代码所属递归类型:structural/acumulative/generative recursion

递归类型分析与代码判断

三种递归的核心差异

  • 结构递归(Structural Recursion):完全跟着数据的天然结构走,比如处理列表就递归调用剩余的cdr部分,处理自然数就用sub1拆成更小的数。递归参数一定是原输入的直接子结构,不需要额外构造参数。
  • 累加递归(Accumulative Recursion):依赖一个“累加器”变量存储中间结果,每一步递归都会更新累加器,最终直接返回累加器的值。且递归调用是函数的最后一步操作(尾递归),不需要在递归返回后再做额外计算。
  • 生成递归(Generative Recursion):不依赖原始数据的结构,完全根据问题的求解逻辑生成新的递归参数。比如二分查找取中间值、枚举试数,参数不是原数据的子结构,是主动根据策略构造出来的。

你的DrRacket代码分析

先贴出代码:

(define (sqrt/nat x)
  (local [(define (sqrt/above x t)
            (if (> (* t t) x)
                (sub1 t)
                (sqrt/above x (add1 t))))]
  (sqrt/above x 1)))

这段代码的逻辑是从t=1开始递增试数,直到t²超过x,返回前一个t(即x的整数平方根)。

结论:属于生成递归

原因如下:

  • 不是结构递归:整个递归过程中x没有被拆解(比如没有对x使用sub1),递归参数(add1 t)和原始输入x的结构没有任何子结构关系,完全是额外构造的。
  • 不是累加递归:没有用累加器存储中间结果,递归调用结束后还需要执行sub1 t的计算,并非直接返回递归结果;全程也没有累积任何中间值,只是不断生成新的t进行尝试。
  • 符合生成递归特征:依靠“枚举试数”的策略主动生成下一个参数,每一步的t都是根据问题逻辑构造的,和原始数据的结构无关。

累加递归与生成递归的核心区别

用实际例子对比更清晰:

  • 累加递归示例(计算阶乘):
    (define (fact n)
      (local [(define (fact-acc n acc)
                (if (zero? n)
                    acc
                    (fact-acc (sub1 n) (* n acc))))]
        (fact-acc n 1)))
    
    这里acc是累加器,每一步把当前n乘到acc中,最终直接返回acc——递归调用是函数的最后一步,无需额外计算。
  • 生成递归就是你这段代码,或是二分查找这类逻辑:参数是根据问题求解策略主动构造的,既不是原始数据的子结构,也不需要累加器存储中间结果。

内容的提问来源于stack exchange,提问作者tim123908

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 13:17:24