如何在 Scheme 中将列表分成两部分
How to split a list into two parts in Scheme
示例:(split '(1 2 3 4) '3)
答案应该是:((1 2 3) 4)
函数需要1个列表和1个数字,输出应该是嵌套列表
嵌套列表由 "mylist" 中等于或小于 "num" 的所有元素组成,较大的数字应位于列表右侧。
我试过了,但输出的只是一个列表:
(define (split mylist num)
(cond
((null? mylist)'())
((list? (car mylist))(split(car mylist) num))
((> (car mylist) num)(split(cdr mylist) num))
(else(cons (car mylist) (split(cdr mylist) num)))))
一个简单的解决方案:
(define (split-list xs y)
(define (less x) (<= x y))
(define (greater x) (> x y))
(list (filter less xs)
(filter greater xs)))
备选方案:
(define (split-list xs y)
(define (less x) (<= x y))
(define-values (as bs) (partition less xs))
(list as bs))
(split-list '(1 2 3 4) 3)
这是一种可能的解决方案,使用 Racket 中的内置程序:
(define (split mylist num)
(cons
(takef mylist (lambda (n) (<= n num)))
(dropf mylist (lambda (n) (<= n num)))))
例如:
(split '(1 2 3 4) 3)
=> '((1 2 3) 4)
(split '(1 2 3 4 5) 3)
=> '((1 2 3) 4 5)
这是使用命名 let
滚动您自己的版本。它使一次通过数据,结果是相反的顺序,因为它是最有效的。
(define (binary-bucket-sort lst threshold)
(let loop ((lst lst) (less-equal '()) (greater '()))
(cond ((null? lst)
(cons less-equal greater))
((<= (car lst) threshold)
(loop (cdr lst) (cons (car lst) less-equal) greater))
(else
(loop (cdr lst) less-equal (cons (car lst) greater))))))
(binary-bucket-sort '(1 5 9 2 6 10 3 7 9 8 4 0) 5)
; ==> ((0 4 3 2 5 1) . (8 9 7 10 6 9))
如果您对 Racket 中的一些更实用的结构感到满意,例如 curry
等,您可以使用这种相当紧凑的方法:
(define (split-list xs y)
(call-with-values (thunk (partition (curry >= y) xs)) cons))
> (split-list '(1 2 3 4 5 6 7) 3)
'((1 2 3) 4 5 6 7)
示例:(split '(1 2 3 4) '3)
答案应该是:((1 2 3) 4)
函数需要1个列表和1个数字,输出应该是嵌套列表 嵌套列表由 "mylist" 中等于或小于 "num" 的所有元素组成,较大的数字应位于列表右侧。
我试过了,但输出的只是一个列表:
(define (split mylist num)
(cond
((null? mylist)'())
((list? (car mylist))(split(car mylist) num))
((> (car mylist) num)(split(cdr mylist) num))
(else(cons (car mylist) (split(cdr mylist) num)))))
一个简单的解决方案:
(define (split-list xs y)
(define (less x) (<= x y))
(define (greater x) (> x y))
(list (filter less xs)
(filter greater xs)))
备选方案:
(define (split-list xs y)
(define (less x) (<= x y))
(define-values (as bs) (partition less xs))
(list as bs))
(split-list '(1 2 3 4) 3)
这是一种可能的解决方案,使用 Racket 中的内置程序:
(define (split mylist num)
(cons
(takef mylist (lambda (n) (<= n num)))
(dropf mylist (lambda (n) (<= n num)))))
例如:
(split '(1 2 3 4) 3)
=> '((1 2 3) 4)
(split '(1 2 3 4 5) 3)
=> '((1 2 3) 4 5)
这是使用命名 let
滚动您自己的版本。它使一次通过数据,结果是相反的顺序,因为它是最有效的。
(define (binary-bucket-sort lst threshold)
(let loop ((lst lst) (less-equal '()) (greater '()))
(cond ((null? lst)
(cons less-equal greater))
((<= (car lst) threshold)
(loop (cdr lst) (cons (car lst) less-equal) greater))
(else
(loop (cdr lst) less-equal (cons (car lst) greater))))))
(binary-bucket-sort '(1 5 9 2 6 10 3 7 9 8 4 0) 5)
; ==> ((0 4 3 2 5 1) . (8 9 7 10 6 9))
如果您对 Racket 中的一些更实用的结构感到满意,例如 curry
等,您可以使用这种相当紧凑的方法:
(define (split-list xs y)
(call-with-values (thunk (partition (curry >= y) xs)) cons))
> (split-list '(1 2 3 4 5 6 7) 3)
'((1 2 3) 4 5 6 7)