1

编写一个过程(前半部分 lst),它返回一个包含前半部分元素的列表。如果给定列表的长度是奇数,则返回的列表应该有 (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)
4

3 回答 3

4

This is pretty simple to implement in terms of existing procedures, check your interpreter's documentation for the availability of the take procedure:

(define (first-half lst)
  (take lst (quotient (length lst) 2)))

Apart from that, the code provided in the question is basically reinventing take, and it looks correct. The only detail left to implement would be, how to obtain the half of the lists' length? same as above, just use the quotient procedure:

(define (first-half lst)
  (list-head lst (quotient (length lst) 2)))
于 2013-06-27T20:29:25.690 回答
2

It looks like you are learning about recursion? One recursive approach is to walk the list with a 'slow' and 'fast' pointer; when the fast pointer reaches the end you are done; use the slow pointer to grow the result. Like this:

(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))))))
于 2013-06-27T21:45:52.357 回答
0

另一种方法是使用一个函数将列表划分为特定索引,然后使用一个包装器来计算 floor(length/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)))
于 2013-07-26T21:57:52.633 回答