Recursion 复制长度函数的有效方法
我正在复制racket的length函数,使用car&cdr比较两个列表的长度,并返回两个列表中较短的一个 简单地说,长度函数是:Recursion 复制长度函数的有效方法,recursion,scheme,lisp,racket,Recursion,Scheme,Lisp,Racket,我正在复制racket的length函数,使用car&cdr比较两个列表的长度,并返回两个列表中较短的一个 简单地说,长度函数是: (define length (lambda (list) (if (null? list) 0 (+ 1 (length (cdr list)))))) 当用于比较两个列表时 (define short (lambda (list1 list2) (if (<= (length list1) (leng
(define length
(lambda (list)
(if (null? list)
0
(+ 1 (length (cdr list))))))
当用于比较两个列表时
(define short
(lambda (list1 list2)
(if (<= (length list1) (length list2))
list1
list2)))
> (short '(a b c) '(1 2 3 4 5 6 7))
我建议这样开始:
(define (shorter list-1 list-2) (shorter-loop list-1 list-2 list-1 list-2))
然后
其中,helper函数shorter循环同时向下递归list-1和list-2。如果list-1变为null,则返回结果-1;如果list-2变为null,则返回结果-2。您的
更短?
过程已经尽可能地高效了-和和或特殊形式短路,并且在任何计算表达式的值为true
(对于或特殊表单)或false
(对于和特殊表单)。因此,一旦其中一个列表达到null
,递归就会停止。您的shorter?
实现相当于,并且与此一样高效:
(define shorter?
(lambda (list1 list2)
(cond ((null? list2) #f)
((null? list1) #t)
(else (shorter? (cdr list1) (cdr list2))))))
如果您想要更紧凑的解决方案,可以使用命名的let
(如另一个答案中所示)或内部帮助程序将两个过程放在一个过程中,这两个过程都是等效的。我将演示后面的方法:
(define (shorter lst1 lst2)
(define (shorter-list list1 list2)
(cond ((null? list2) lst2)
((null? list1) lst1)
(else (shorter-list (cdr list1) (cdr list2)))))
(shorter-list lst1 lst2))
“named let”方法提供易于理解的代码。注释提供了解释:
(define (shorter l1 l2)
(let loop ((al l2) ; start with both full lists
(bl l2))
(cond
[(empty? al) l1] ; if al finishes, return l1 and end;
[(empty? bl) l2] ; if bl finishes, return l2 and end;
[else
(loop (cdr al) (cdr bl))] ; else loop again with cdr of lists;
)))
此功能将在Shorrer列表完成时结束,并且不会不必要地继续到较长列表的末尾。这并不能回答问题
(define (shorter lst1 lst2)
(define (shorter-list list1 list2)
(cond ((null? list2) lst2)
((null? list1) lst1)
(else (shorter-list (cdr list1) (cdr list2)))))
(shorter-list lst1 lst2))
(define (shorter l1 l2)
(let loop ((al l2) ; start with both full lists
(bl l2))
(cond
[(empty? al) l1] ; if al finishes, return l1 and end;
[(empty? bl) l2] ; if bl finishes, return l2 and end;
[else
(loop (cdr al) (cdr bl))] ; else loop again with cdr of lists;
)))