所以我在这里有一些我想要使用的定义列表:
(DEFINE list0 (LIST 'j 'k 'l 'm 'n 'o 'j) )
(DEFINE list1 (LIST 'a 'b 'c 'd 'e 'f 'g) )
(DEFINE list2 (LIST 's 't 'u 'v 'w 'x 'y 'z) )
(DEFINE list3 (LIST 'j 'k 'l 'm 'l 'k 'j) )
(DEFINE list4 (LIST 'n 'o 'p 'q 'q 'p 'o 'n) )
(DEFINE list5 '( (a b) c (d e d) c (a b) ) )
(DEFINE list6 '( (h i) (j k) l (m n) ) )
(DEFINE list7 (f (a b) c (d e d) (b a) f) )
我想要做的是为'中间'函数创建一个递归函数,如下所示:
MIDDLE: (中间第1个)应该返回一个仅包含第一个元素的中间元素的单元素列表[如果第一个元素中有偶数个元素,则返回空列表]。也就是说,
(middle '(a b c d e f g) )
应该/将返回:
(d)
(middle '(s t u v w x y z) )
应该/将返回空字符串。
(middle '( (a b) c (d e d) c (b a) ) )
应该/将返回:
( (d e d) )
请注意,( (d e d) )
是一个包含中间事物的列表,它本身就是一个列表。
我认为我必须把它分成两个问题。 首先,我需要一个可以选择列表第n项的函数。我对它的创造知之甚少。 其次,您需要一个函数来确定中期的位置以及是否存在中期。 (我对如何创建它也知之甚少。 然后
(define middle
(lambda (L)
(if (middle? L)
(nth-term (middle L) L)
'())))
这是我的evens功能,我想知道是否有更容易的方法:
(define evens
(lambda (L)
(if (or (NULL? (cddr L)))
'()
(cons (cadr L) (evens (cddr L))))))
答案 0 :(得分:3)
最简单的方法是使用length函数获取列表的长度,然后确保长度不是偶数(如果是,则返回空列表)。一旦我们知道长度是奇数,返回列表的一半长度减去一个的元素。结果是列表的中间部分。以下是代码的实际内容:
(define (middle lis)
(let ((list-length (length lis)))
(if (even? list-length)
'()
(list (list-ref lis (/ (- list-length 1) 2))))))
要回答主题行中的问题,请使用list-ref过程获取列表的第n项,如下所示:
> (list-ref '(a b c d) 2)
'c
如果您仍然感到困惑,请告诉我,我会尽力澄清。
答案 1 :(得分:2)
答案可以改进如下:
(define (middle lst)
(let ((len (length lst)))
(if (even? len)
'()
(list (list-ref lst (quotient len 2))))))
请注意,有一种更简单的方法可以获得中间元素的索引。
答案 2 :(得分:2)
显而易见的方法(计算长度;除以2;搜索列表)需要两次遍历列表。
这是一种只需要一次通过的替代方案:
(define (middle lst)
(letrec
((middle-odd
(lambda (x y) (if (null? x) (list (car y)) (middle-even (cdr x) (cdr y)))))
(middle-even
(lambda (x y) (if (null? x) '() (middle-odd (cdr x) y)))))
(middle-even lst lst)))