Racket 用球拍分割名单

Racket 用球拍分割名单,racket,Racket,给定一个列表和一个数字n,我试图将一个列表分成两个独立的列表:一个列表长度为n,第二个列表是原始列表的其余部分 以下是我所拥有的: (define (part lst i) (if (> i 0) (list (append (list (first lst)) (list (part (rest lst) (- i 1))))) (append lst))) 其中lst是输入的列表,i是编号。当我输入带有数字2的列表'(1234)时,我返回的输出是:'((1)((2(34)'))),而

给定一个列表和一个数字n,我试图将一个列表分成两个独立的列表:一个列表长度为n,第二个列表是原始列表的其余部分

以下是我所拥有的:

(define (part lst i)
(if (> i 0)
(list (append (list (first lst)) (list (part (rest lst) (- i 1)))))
(append lst)))
其中lst是输入的列表,i是编号。当我输入带有数字2的列表'(1234)时,我返回的输出是:'((1)((2(34)'))),而不是我想要的'((12)(34))

这是一个家庭作业,如果有人能给我指出问题所在的正确方向,我将不胜感激,因为这是一个硬件作业,我只能使用简单的racket函数

编辑:

当我将代码更改为:

(define (part lst i)
(if (> i 0)
(append (list (first lst)) (list (part (rest lst) (- i 1))))
(append lst)))

使用现有的库,我得到了一个'(1(2(34))。

在Racket中有一个简单的方法来解决这个问题,只需使用内置的过程(也可以在库中找到)。这样做的优点是只需在输入列表中进行一次传递:

(define (part lst i)
  (let-values (((head tail) (split-at lst i)))
    (list head tail)))
(define (part lst i)
  (list (take lst i)
        (drop lst i)))
另一种选择是使用Racket的内置程序和(也可在SRFI-1中使用)-但这将在输入列表中进行两次传递:

(define (part lst i)
  (let-values (((head tail) (split-at lst i)))
    (list head tail)))
(define (part lst i)
  (list (take lst i)
        (drop lst i)))
从头开始实施

为了构建我们自己的解决方案,我们可以编写一个过程来进行一次传递,如下所示:

(define (part lst i)
  (if (negative? i)
      (error "index can't be negative")
      (let loop ((lst lst) (acc '()) (i i))
        (cond ((and (empty? lst) (positive? i))
               (error "index is too large for list"))
              ((zero? i)
               (list (reverse acc) lst))
              (else
               (loop (rest lst) (cons (first lst) acc) (sub1 i)))))))
此外,我们还可以实现自己版本的
take
drop
——同样,这将遍历输入列表两次:

(define (my-take lst i)
  (if (> i 0)
      (cons (first lst)
            (my-take (rest lst) (- i 1)))
      '()))

(define (my-drop lst i)
  (if (> i 0)
      (my-drop (rest lst) (- i 1))
      lst))

(define (part lst i)
  (list (my-take lst i)
        (my-drop lst i)))

你真的必须深入到基本知识中去,学习
的cons
以及如何将成对的元素链接在一起成为列表,因为你使用
附加
列表
列表
(你可能期望
rest
重新生成一个列表)似乎您需要并且您需要完全停止使用
list
append
。作为家庭作业,重点是从基本操作实现这些功能,而不是使用现有版本。@AndrewMedico-mmm,我正打算这么做。别急着投反对票!然后在写完之前不要提交答案。投票的依据是当时实际可见的内容,而不是以后可能出现的内容。@AndrewMedico太糟糕了,你不能否决评论,但我不同意。@ChrisJester Young我用你的建议扩展了我的答案。这么多选择!