比较两个列表中的元素并添加不同的元素

时间:2013-12-07 22:05:49

标签: list scheme racket sublist

我的问题是。我有一个子列表(slst1),其中包含来自另一个列表(lst)的随机元素。然后,我需要创建另一个(slst2),其中包含不在slst1中的lst元素,但是,当我比较它们时,结果不是我所期望的。

电话会是:

(split 0.3 lst)

其中'0.3'是我想要的列表的一部分。

包含:

((a11 a12 a13 a14)(a21 a22 a32 a42) (a31 a32 a33 a34))

,例如,slst1包含:

((a21 a22 a23 a24))

然后,slst2应该包含:

((a11 a12 a13 a14) (a31 a32 a33 a34))

但是,使用我的代码,slst2总是包含与lst相同的项目,而不仅仅是不同的项目。

这是我的代码:

(define (split proportion lst)
(let((ne (* proportion (length lst)))(slst1 '())(slst2 '()))
;Calculate first sublist
(when (> ne 0)
  (for ([i (inexact->exact ne)])
    (if (null? lst)
       (set! slst1 (list-ref lst (random (length lst))))
       (set! slst1 (list lst (list-ref lst (random (length lst)))))))
 ;Try to calculate second sublist 
   (for ([i (length lst)]
     #:when (not(member (list-ref lst i) slst1)))
  (set! slst2 (list slst2 (list-ref lst i)))
     )
 slst2)))

我是Racket的诺言,所以任何建议都是完美的。感谢您阅读/询问。

1 个答案:

答案 0 :(得分:0)

如果我理解正确,我会这样做:

(define (split proportion lst)
  (define le (length lst))
  (define slst1 
    (for/list ([i (inexact->exact (round (* proportion le)))]) 
      (list-ref lst (random le))))
  (define slst2 
    (for/list ([e (in-list lst)] #:unless (member e slst1)) 
      e))
  (values slst1 slst2))

然后

(split 0.5 '((a11 a12 a13 a14)(a21 a22 a32 a42) (a31 a32 a33 a34) (a41 a42 a43 a44)))
=> '((a11 a12 a13 a14) (a21 a22 a32 a42))
   '((a31 a32 a33 a34) (a41 a42 a43 a44))

请注意,slst1可以多次包含相同的成员,因此(长度slst1)+(长度slst2)可以大于(长度lst)。此外,如果成员在初始列表中出现多次,您可能会得到奇怪的结果。

如果你想避免这种情况,可以选择以下方法:

(define (split prop lst)
  (for/fold ((s1 '()) (s2 lst)) ([i (inexact->exact (round (* (length lst) prop)))])
    (define rn (random (length s2)))
    (values 
     (cons (list-ref s2 rn) s1)
     (append (take s2 rn) (drop s2 (add1 rn))))))

s1初始化为null,s2为lst。每当我们向s1添加一个元素时,我们都会将它从s2中删除。