球拍 - 分开偶数和奇数?

时间:2014-03-24 19:11:09

标签: list racket sublist

我试图在Racket / Scheme中构建一个函数,在这里你得到一个整数列表,然后它必须将它们分成两个子列表,一个用于偶数,一个用于奇数。我是一个非常新的球拍,我有一些基本的操作列表,但我无法弄清楚如何定义两个子列表并在每个子列表中放置数字。

这是我到目前为止所做的:

    (define (segregate lst)
      (if (empty? lst)
          '()
          (if (even? (car a lst))
              (append (car alst) (segregate (cdr alst))))

从那里我被卡住了。因此,如果条件,偶数将被分类到一个列表中。但我也需要奇数。在这种情况下的else语句会给你那些奇数,但我不知道如何将它们放入一个单独的列表中。

这是我第一次真实地在这个网站上提问,因为我的教授出于某种原因不在他的办公室。

5 个答案:

答案 0 :(得分:1)

所以,你的函数需要返回两个列表,对吧?你的基本案例需要返回两个空列表,然后在递归的情况下,你需要填写相关的列表。这是一些骨架代码(填写<???>):

(define (odds-and-evens lst)
  (if (null? lst)
      (values '() '())
      (let-values (((odds evens) (odds-and-evens (cdr lst))))
        (cond ((odd? (car lst)) (values (cons <???> <???>) <???>))
              ((even? (car lst)) (values <???> (cons <???> <???>)))
              (else (values odds evens))))))

答案 1 :(得分:1)

克里斯&#39; let-values - 版本很辣,但我会这样编写它以使其尾递归:

(define (split left? lst)
  (let loop ((lst lst) (a '()) (b '()))
    (if (null? lst)
        ;; you don't need to use values. `cons` or `list` are sometimes preferred
        (values (reverse a) (reverse b)) 
        (let ((e (car lst)))
          (if (left? e)
              (loop (cdr <???>) (cons <???> <???>) <???>)
              (loop (cdr <???>) <???>  (cons <???> <???>)))))))

(split odd? '(1 2 3 4 ...)) 
; ==> 
; (1 3 ...)
; (2 4 ...)

即使它遍历两个列表两次(一个用于分离而另一个用于反向),它仍然快了很多倍,并且IMO更容易遵循。

如果您不关心订单,那么您只需跳过reverse步骤,它就会更快。

答案 2 :(得分:1)

以上代码令人困惑。 Racket是一种非常简单的语言,它旨在了解代码在您阅读时所执行的操作。您可以使用尾递归来解决此问题。

分析A的第一个元素,将其放在应该的位置,然后再次调用该函数,直到A为空。

(define segregate
  (lambda (A o e) ;A is the list of integers, o is the list of odds and e is for evens.
      (cond ((empty? A) (list o e))
            ((even? (car A)) (segregate (cdr A) o (append e (car A)))
            (else (segregate (cdr A) (append o (car A)) e))))) 

答案 3 :(得分:1)

使用内置partition

(define (segregate lst)
  (let-values ([(e o) (partition even? lst)])
    (list e o)))

答案 4 :(得分:1)

另一种选择是使用foldr

(define (odd-even xs)
  (foldr (lambda (x b)
           (if (odd? x)
               (list (cons x (first b)) (second b))
               (list (first b) (cons x (second b))))) '(()()) xs))

racket@> (odd-even '(1 2 3 4 5 6 7))
'((1 3 5 7) (2 4 6))