函数式语言递归调用退出问题——Racket语言实现求助
解决Racket递归函数空列表报错问题
你的问题出在没有处理空列表这个基准情况——当递归到最后,列表被rest剥成空时,(first L)会直接报错,因为空列表没有第一个元素。函数式编程里处理列表递归,第一步就要先判断列表是否为空,这是终止递归的核心。
另外你提到要“将匹配的标记加入结果列表”,但原代码没有做结果收集,只是单纯递归,我也一起修正了:
(define (first-item L) ;; 基准情况:空列表直接返回空,终止递归 (if (empty? L) '() (let ([item (first L)]) (cond ;; 匹配符号或数字时,把当前元素加入结果,再递归处理剩余列表 [(regexp-match #rx"[-()+*]" (make-string 1 item)) (cons item (first-item (rest L)))] [(regexp-match #px"[0-9]" (make-string 1 item)) (cons item (first-item (rest L)))] ;; 不匹配的元素跳过,直接递归处理剩下的 [else (first-item (rest L))]))))
关键修改说明:
- 开头的
(empty? L)判断就是退出条件,一旦列表为空就返回空列表,不会再执行后面的(first L),彻底避免报错。 - 用
(cons item ...)把匹配到的元素添加到结果列表头部,递归处理剩余列表后拼接起来,符合你收集结果的需求。 - 补充了
else分支,处理不匹配的元素,直接跳过当前元素继续递归。
如果想让代码更简洁,可以把两个正则表达式合并成一个,逻辑完全一致:
(define (first-item L) (if (empty? L) '() (let ([item (first L)]) (if (regexp-match #rx"[-()+*0-9]" (make-string 1 item)) (cons item (first-item (rest L))) (first-item (rest L))))))
内容的提问来源于stack exchange,提问作者mikedoorhandle
相关产品推荐
相关产品推荐

