编写一个程序(上半部分),返回一个包含其前半部分元素的列表。如果给定列表的长度为奇数,则返回的列表应具有(length - 1)/ 2个元素。
我给这些程序作为一个例子,因为我是Scheme的新手,我需要你帮助解决这个问题。
(define list-head
(lambda (lst k)
(if (= k 0)
'()
(cons (car lst)(list-head (cdr lst)(- k 1)))))))
(list-head '(0 1 2 3 4) 3)
; list the first 3 element in the list (list 0 1 2)
我想要的程序的预期输出是:
(first-half '(43 23 14 5 9 57 0 125))
(43 23 14 5)
答案 0 :(得分:4)
根据现有程序实现这一点非常简单,请检查解释器的文档以了解take
过程的可用性:
(define (first-half lst)
(take lst (quotient (length lst) 2)))
除此之外,问题中提供的代码基本上是重新发明take
,看起来是正确的。剩下要实现的唯一细节是,如何获得列表长度的一半?与上述相同,只需使用quotient
程序:
(define (first-half lst)
(list-head lst (quotient (length lst) 2)))
答案 1 :(得分:2)
看起来你正在学习递归?一种递归方法是使用“慢”和“快速”指针遍历列表;当快速指针到达终点时,你就完成了;使用慢速指针来增长结果。像这样:
(define (half list)
(let halving ((rslt '()) (slow list) (fast list))
(if (or (null? fast) (null? (cdr fast)))
(reverse rslt)
(halving (cons (car slow) rslt)
(cdr slow)
(cdr (cdr fast))))))
答案 2 :(得分:0)
另一种接近它的方法是使用一个函数在特定索引处划分列表,然后使用包装器来计算楼层(长度/ 2):
(define (cleave_at n a)
(cond
((null? a) '())
((zero? n) (list '() a))
(#t
((lambda (x)
(cons (cons (car a) (car x)) (cdr x)))
(cleave_at (- n 1) (cdr a))))))
(define (first-half a)
(car (cleave_at (floor (/ (length a) 2)) a)))