【问题标题】:Taking groups of elements randomly in scheme方案中随机取元素组
【发布时间】:2019-04-20 03:06:45
【问题描述】:

如何在 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. 获得的所有子列表吗?

【问题讨论】:

  • 您使用的是哪个 Scheme 变体?是兼容 R6RS、兼容 R5RS、Racket 还是其他?
  • 我正在终端中运行“mzscheme”,如下所示:stackoverflow.com/questions/1175977/…
  • 等等,我刚刚意识到您的示例输出不是随机的。你想随机化什么,内容(正如我在回答中所做的那样)或子列表的长度?
  • 内容,和你一样。谢谢。
  • 好吧,没关系:)。不客气!

标签: functional-programming scheme lisp


【解决方案1】:

如果我们将问题分解成块会更容易。首先,让我们编写几个程序,允许我们从列表中取出或删除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))

【讨论】:

  • 谢谢。我的方法不同,需要一种我无法解决的递归:1. 随机抽取一组元素 2. 剪切列表,删除第一组和 3. 在这个过程中递归。我有 1. 和 2. 正常工作,但在 3. 上失败了。
  • 有什么建议可以用我的想法递归地做吗?
  • 好吧,您应该编辑您的帖子并将代码添加为问题的一部分。但这与我的方法基本相同:首先随机化列表,然后获取正确大小的块。诀窍是将问题拆分成更小的部分,每个部分都专注于一个问题。
  • 好的,我自己试试看。
猜你喜欢
  • 1970-01-01
  • 2013-11-14
  • 2018-05-03
  • 2015-01-31
  • 1970-01-01
  • 2011-04-18
  • 1970-01-01
  • 2023-04-06
  • 1970-01-01
相关资源
最近更新 更多