如何在 Scheme 中实现一个程序,获取给定列表的元素并返回一个新列表,其中元素是前一个列表的随机集合?我希望它可以工作任何长度。例如:
输入:'(a e i o u)
,输出:'((a e) (i o) (u))
长度为 2。
我的尝试(使用 for/list)很笨拙并且基于递归。我按照 Óscar 的建议划分了任务:
从列表 l 中随机选择 n 个元素:
(define (pick-n-random l n) (take (shuffle l) n))
从列表 l1 中删除列表 l2:
(define (cut l1 l2) (cond ((null? l1) '()) ((not (member (car l1) l2)) (cons (car l1) (cut (cdr l1) l2))) (else (cut (cdr l1) l2))))
那么,这就是我的问题:我如何递归这个过程以获得预期的程序?我是否应该使用 for/list
粘贴此过程 1. 和 2. 获得的所有子列表?
最佳答案
如果我们将问题拆分成多个 block 会更容易。首先,让我们编写几个程序,允许我们从列表中获取或删除 n
元素,如果列表中没有足够的元素(如果不是这样,我们可以已使用内置的 take
和 drop
):
(define (take-up-to lst n)
(if (or (<= n 0) (null? lst))
'()
(cons (car lst) (take-up-to (cdr lst) (sub1 n)))))
(define (drop-up-to lst n)
(if (or (<= n 0) (null? lst))
lst
(drop-up-to (cdr lst) (sub1 n))))
有了以上两个过程,就可以很容易地创建另一个过程来将列表中的元素分组为 n 个大小的子列表:
(define (group lst n)
(if (null? lst)
'()
(cons (take-up-to lst n)
(group (drop-up-to lst n) n))))
最后,我们将我们的分组过程与 shuffle
相结合,随机化列表的内容:
(define (random-groups lst n)
(group (shuffle lst) n))
它按预期工作:
(random-groups '(a e i o u) 2)
=> '((e a) (u i) (o))
关于functional-programming - 在方案中随机取元素组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53346117/