如何在Scheme中将列表拆分为两部分

时间:2022-09-26 21:38:40

Example: (split '(1 2 3 4) '3)

示例:(拆分'(1 2 3 4)'3)

the Answer should be: ((1 2 3) 4)

答案应该是:((1 2 3)4)

The function required 1 list and 1 number, the output should be nested list the nested list consist of all elements of "mylist" which are equal or less than the "num", and the greater number should be on the right of the list.

该函数需要1个列表和1个数字,输出应该是嵌套列表,嵌套列表由“mylist”的所有元素组成,它们等于或小于“num”,并且更大的数字应该在列表的右侧。

I tried but out put is only one list:

我试过但是输出只是一个列表:

(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)))))

4 个解决方案

#1


Here's one possible solution, using built-in procedures in Racket:

这是一种可能的解决方案,使用Racket中的内置程序:

(define (split mylist num)
  (cons
   (takef mylist (lambda (n) (<= n num)))
   (dropf mylist (lambda (n) (<= n num)))))

For example:

(split '(1 2 3 4) 3)
=> '((1 2 3) 4)

(split '(1 2 3 4 5) 3)
=> '((1 2 3) 4 5)

#2


A simple solution:

简单的解决方案:

(define (split-list xs y) 
  (define (less x)    (<= x y))
  (define (greater x) (>  x y))
  (list (filter less xs)
        (filter greater xs)))

An alternative:

(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)

#3


This is roll your own version using named let. It makes one pass through the data and the result is in reverse order since it's the most effective.

这是使用名为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))

#4


If you're comfortable with some of the more functional constructs in Racket, such as curry and the like, you can use this rather compact approach:

如果您对Racket中的一些功能更强的构造感到满意,例如咖喱等,您可以使用这种相当紧凑的方法:

(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)

#1


Here's one possible solution, using built-in procedures in Racket:

这是一种可能的解决方案,使用Racket中的内置程序:

(define (split mylist num)
  (cons
   (takef mylist (lambda (n) (<= n num)))
   (dropf mylist (lambda (n) (<= n num)))))

For example:

(split '(1 2 3 4) 3)
=> '((1 2 3) 4)

(split '(1 2 3 4 5) 3)
=> '((1 2 3) 4 5)

#2


A simple solution:

简单的解决方案:

(define (split-list xs y) 
  (define (less x)    (<= x y))
  (define (greater x) (>  x y))
  (list (filter less xs)
        (filter greater xs)))

An alternative:

(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)

#3


This is roll your own version using named let. It makes one pass through the data and the result is in reverse order since it's the most effective.

这是使用名为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))

#4


If you're comfortable with some of the more functional constructs in Racket, such as curry and the like, you can use this rather compact approach:

如果您对Racket中的一些功能更强的构造感到满意,例如咖喱等,您可以使用这种相当紧凑的方法:

(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)