[英]Split a list into a posn in Racket
我有这个 function ,它接受一个列表和一个数字,并将列表拆分到第 n 个元素并使其成为 posn,例如:
(split (list 1 2 3 4) 2) = (make-posn (list 1 2) (list 3 4))
(split (list 1 2 3 4) 0) = (make-posn empty (list 1 2 3 4))
(split (list empty 23) = (make-posn empty empty)
(split (list 1 2 3 4) 1) = (make-posn (list 1) (list 2 3 4))
关键是,我有一个辅助 function 来制作第一部分
(define (aux l n)
(cond[(empty? l) empty]
[(zero? n) empty]
[(positive? n) (cons (first l)(aux (rest l)(sub1 n)))]))
(aux (list 1 2 3 4) 2)) = (list 1 2)
但我不知道如何制作第二部分
你肯定走上了正轨! 您可以创建第二个aux2
循环以类似方式构建 output 的第二部分 -
(define (split l n)
;; left portion (your code)
(define (aux1 l n)
(cond
[(empty? l) empty]
[(zero? n) empty]
[(positive? n)
(cons (first l)
(aux1 (rest l)
(sub1 n)))]))
;; right portion (new code)
(define (aux2 l n)
(cond
[(empty? l) empty]
[(zero? n) l]
[(positive? n)
(aux2 (cdr l)
(sub1 n))]))
;; combine
(posn (aux1 l n) (aux2 l n)))
上面我们使用了posn
,它是根据您问题中的数据结构建模的 -
(struct posn (l r) #:transparent )
您以其他方式编写split
。 我们可以将aux1
和aux2
合并为一个aux
-
(define (split ls n)
(define (aux n l r)
(cond
[(or (empty? r) (zero? n))
(posn (reverse l) r)]
[(positive? n)
(aux (sub1 n)
(cons (car r) l)
(cdr r))]
[else
(error 'split "cannot split using a negative number")]))
(aux n empty ls))
或者我们可以使用 continuation-passing 风格编写aux
-
(define (split t n)
(define (aux t n return)
(cond
[(or (empty? t) (zero? n))
(return empty t)]
[(positive? n)
(aux (cdr t)
(sub1 n)
(lambda (l r)
(return (cons (car t) l) r)))]
[else
(error 'split "cannot split using a negative number")]))
(aux t n posn))
使用您问题中的示例-
(split (list 1 2 3 4) 2)
(split (list 1 2 3 4) 0)
(split empty 23)
(split (list 1 2 3 4) 1)
上述split
的每个实现都会产生相同的 output -
(posn '(1 2) '(3 4))
(posn '() '(1 2 3 4))
(posn '() '())
(posn '(1) '(2 3 4))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.