【问题标题】:Scheme return a list with first half of its elementsScheme 返回一个包含前半部分元素的列表
【发布时间】:2013-06-27 20:26:25
【问题描述】:

编写一个过程(前半部分 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)

【问题讨论】:

    标签: scheme


    【解决方案1】:

    就现有过程而言,这很容易实现,请查看您的解释器文档以了解take 过程的可用性:

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

    除此之外,问题中提供的代码基本上是在重新发明take,它看起来是正确的。剩下要实现的唯一细节是,如何获得列表长度的一半?同上,只需使用quotient 程序:

    (define (first-half lst)
      (list-head lst (quotient (length lst) 2)))
    

    【讨论】:

    • 地板,不是天花板。 :-) 但你可以使用quotient
    【解决方案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))))))
    

    【讨论】:

    • +Chris J-Y,感谢您的拼写编辑。 +Chris T,我喜欢“list”,而不是“lst”
    【解决方案3】:

    另一种处理方法是使用一个函数在特定索引处划分列表,然后使用一个包装器来计算 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)))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-09
      • 1970-01-01
      • 2022-12-05
      • 1970-01-01
      • 1970-01-01
      • 2014-12-20
      • 1970-01-01
      相关资源
      最近更新 更多