【问题标题】:Racket language Accumulator tail recursive球拍语言累加器尾递归
【发布时间】:2022-10-06 03:15:58
【问题描述】:
我正在尝试使用连接两个排序列表的累加器编写尾递归函数。
输入:(40 43 50)(42 46 48)
输出:(40 42 43 46 48 50)
它需要进行尾递归,我们将累加器调用到另一个函数。我陷入了累加器功能需要做的事情。
(define (rec l1 l2 acc))
(rec (rest l1) l2)
(define (foo l1 l2)
(cond
((null? l1) l2)
((null? l2) l1)
(else
(cond
((<= (car l1) (car l2)) (rec (l2 (cons (first l1) (acc))))
((> (car l1) (car l2)) (rec (l1 (cons (first l2) (acc))))
))))))
标签:
list
recursion
racket
tail
accumulator
【解决方案1】:
您正在使用 l1 或 l2 甚至将列表称为函数,但这是行不通的。实际上,您需要反对累加器参数。这是使用尾递归和累加器的反向示例:
(define (reverse lst)
(reverse-helper lst '()))
(define (reverse-helper lst acc)
(if (null? lst)
acc ; acc already in reverse
(reverse-helper (cdr lst) (cons (car lst) acc))))
您还可以将帮助程序保留在本地:
(define (reverse lst)
(define (helper lst acc)
(if (null? lst)
acc ; acc already in reverse
(helper (cdr lst) (cons (car lst) acc))))
(helper lst '()))
您的版本需要更多案例。例如。 l1 和 l2 为空时的基本情况。 l1 或 l2 为空的两种情况,然后是最后一种情况,您将 l1 和 l2 和 cdr 的第一个元素中的最低者用于下一个。因此您会看到如果您在其开头跟踪或添加断点,则类似这样:
(merge-helper '(1 3 5 6 7) '(2 3 4) '()) ; ==>
(merge-helper '(3 5) '(2 3 4) '(1)) ; ==>
(merge-helper '(3 5) '(3 4) '(2 1)) ; ==>
(merge-helper '(5) '(3 4) '(3 2 1)) ; ==>
(merge-helper '(5) '(4) '(3 3 2 1)) ; ==>
(merge-helper '(5 6 7) '() '(4 3 3 2 1)) ; ==>
(merge-helper '() '() '(7 6 5 4 3 3 2 1)) ; ==>
(reverse '(7 6 5 4 3 3 2 1)) ; ==>
(1 2 3 3 4 5 6 7)
祝你好运
【解决方案2】:
您还可以使用可选参数将其放在一个函数中:
(define (merge l1 l2 (acc '()) (test <))
(cond ((and (null? l1) (null? l2)) (reverse acc))
((null? l1) (merge '() (cdr l2) (cons (car l2) acc)))
((null? l2) (merge (cdr l1) '() (cons (car l1) acc)))
((test (car l1) (car l2)) (merge (cdr l1) l2 (cons (car l1) acc)))
(else (merge l1 (cdr l2) (cons (car l2) acc)))))