Programming languages 断尾递归?
我学习过编程语言课程,幻灯片中有一种方案代码:Programming languages 断尾递归?,programming-languages,scheme,tail-recursion,Programming Languages,Scheme,Tail Recursion,我学习过编程语言课程,幻灯片中有一种方案代码: ; (listof any) -> (listof any[no-cons]) (define (remove-pairs l) (cond [(empty? l) '()] [else (let ([ans (if (cons? (first l)) (begin (free! (first l))
; (listof any) -> (listof any[no-cons])
(define (remove-pairs l)
(cond
[(empty? l) '()]
[else
(let ([ans
(if (cons? (first l))
(begin (free! (first l))
(remove-pairs (rest l)))
(cons (first l)
(remove-pairs (rest l))))])
(free! l) ; <- this will break our tail recursion.
ans)]))
;(任何人的列表)->(任何人的列表[无反对意见])
(定义(删除线对l)
(续)
[(空?l)'()]
[其他
(让我们
(如果(反对)(第一个l))
(开始(免费!(第一个l))
(移除配对(其余l)))
(反对(第一个l)
(删除对(其余l)))]
(免费!l)如果不查看免费!
的代码,就不可能知道这个函数应该做什么。可以推断的是,该过程删除列表中不是cons
单元格的每个元素,从一开始就创建并返回一个新列表,其中只包含非cons
单元格的元素
声明函数是尾部递归是不正确的-它从一开始就不是,无论free!
做什么,递归调用都不在尾部位置
下面是使用尾部递归实现推断功能的正确方法,请注意,问题中递归的结构方式完全错误,根本不是尾部递归:
(define (remove-pairs l)
(let loop ((lst (reverse l))
(acc '()))
(cond [(empty? lst)
acc]
[(cons? (first lst))
(free! (first lst)) ; whatever that is
(loop (rest lst) acc)]
[else
(loop (rest lst) (cons (first lst) acc))])))
从更实际的角度来看,您可以使用过滤器
获得相同的功能,尽管这不能保证是尾部递归的:
(define (remove-pairs l)
(filter (lambda (x)
(cond [(cons? x)
(free! x) ; whatever that is
#f]
[else #t]))
l))
无论哪种方式,它都是这样工作的:
(remove-pairs '(1 (2 4) 3 5 (6 8) 7 (9 11)))
=> '(1 3 5 7)