functional-programming - 在方案中随机取元素组

标签 functional-programming scheme lisp

如何在 Scheme 中实现一个程序,获取给定列表的元素并返回一个新列表,其中元素是前一个列表的随机集合?我希望它可以工作任何长度。例如:

输入:'(a e i o u),输出:'((a e) (i o) (u)) 长度为 2。

我的尝试(使用 for/list)很笨拙并且基于递归。我按照 Óscar 的建议划分了任务:

  1. 从列表 l 中随机选择 n 个元素:

    (define (pick-n-random l n)
      (take (shuffle l) n))
    
  2. 从列表 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 元素,如果列表中没有足够的元素(如果不是这样,我们可以已使用内置的 takedrop):

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

相关文章:

python - Python 中更好的函数组合

c++ - 如何在 Haskell 的同一行打印和阅读?

filesystems - 使用 Scheme 将字符串附加到目录中的文件

recursion - Lisp 中的递归加法

scala - Scala 查找数组的所有元素是否具有相同长度的方法是什么?

.net - F# Seq 的一个实现问题

scope - Racket 中的 `match` 可以具有来自外部范围的变量的模式吗?

方案:获取不带括号的 cdr

python - Python中有这样的模式匹配函数吗?

scheme - 压平一次程序