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

递归理解与符号交替判断函数报错排查:first参数异常问题

解决你的Scheme函数报错与递归逻辑问题

首先,咱们先搞定那个报错:first: expects only 1 argument, but found 2。你看代码里的这两行:

[(< (first (rest lst) 0)) (alternating? (rest lst))]
[(> (first (rest lst) 0)) (alternating? (rest lst))]

这里的括号嵌套错了!first只能接受一个参数(就是你要取首元素的列表),但你写成了(first (rest lst) 0),相当于给first传了两个东西:(rest lst)和0,解释器当然会报错。正确的写法应该是先取(rest lst)的首元素,再和0比较,也就是把括号调整成:

[(< (first (rest lst)) 0)]
[(> (first (rest lst)) 0)]

不过光改括号还不够,你的函数还有几个逻辑漏洞,咱们一起理清楚:

递归逻辑的核心问题

判断列表符号交替的递归思路应该是:

  1. 边界情况:如果列表是空的,或者只有一个元素,直接返回true(因为没有违反交替规则的元素)。
  2. 递归步骤:如果当前元素是正数,那下一个元素必须是负数,并且从下一个元素开始的子列表也要满足交替规则;如果当前元素是负数,下一个元素必须是正数,同时子列表也要满足规则。
  3. 特殊情况:如果有元素是0,直接返回false(0既不是正也不是负,不符合交替要求)。

修正后的完整代码

(define (alternating? lst)
  (cond
    [(empty? lst) true]                  ; 空列表符合条件
    [(empty? (rest lst)) true]           ; 单个元素的列表符合条件
    [(> (first lst) 0)
     (and (< (first (rest lst)) 0)       ; 下一个元素必须是负数
          (alternating? (rest lst)))]    ; 递归检查子列表
    [(< (first lst) 0)
     (and (> (first (rest lst)) 0)       ; 下一个元素必须是正数
          (alternating? (rest lst)))]    ; 递归检查子列表
    [else false]))                       ; 元素为0的情况,直接返回false

测试用例验证

你可以用这些check-expect来验证:

(check-expect (alternating? '(1 -2 3 -4)) true)
(check-expect (alternating? '(1 2 3)) false)
(check-expect (alternating? '(-1 2 -3)) true)
(check-expect (alternating? '(0 1)) false)
(check-expect (alternating? '(5)) true)
(check-expect (alternating? '()) true)

再聊聊递归的本质

递归就是把大问题拆解成和原问题结构一致的小问题:比如判断整个列表lst是否交替,等价于判断前两个元素符号相反,并且子列表(rest lst)也满足交替条件。每次递归调用都会让列表变短,直到触发边界条件(空列表或单元素列表),递归就终止了。

你的原代码里没处理单元素列表的情况,当列表只剩一个元素时,(rest lst)是空的,这时候调用(first (rest lst))又会触发新的错误——first不能作用在空列表上,所以必须加一个分支处理单元素的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:51:18