【问题标题】:shuffle list without duplicate number in LispLisp中没有重复数字的随机列表
【发布时间】:2019-11-24 21:45:04
【问题描述】:

我有这个函数来创建一个列表,其中包含来自另一个问题 list with initial-element are start from 99 to 0 in Lisp 的初始元素

(defun newList (&optional(n 100))
  (loop for i from (- n 1) downto 0 collect i))

(defun board (newList &optional(n 10))
  (cond
   ((null newList) nil)
   (t (cons (subseq newList 0 n) (board (subseq newList n) n)))))

(defun show-board (board)
    (format T "~%")
    (mapcar (lambda (x) (format T " ~A ~%" x)) board)
    (format nil "")
)

(show-board (board (newList)))

(99 98 97 96 95 94 93 92 91 90) 
(89 88 87 86 85 84 83 82 81 80) 
(79 78 77 76 75 74 73 72 71 70) 
(69 68 67 66 65 64 63 62 61 60) 
(59 58 57 56 55 54 53 52 51 50) 
(49 48 47 46 45 44 43 42 41 40) 
(39 38 37 36 35 34 33 32 31 30) 
(29 28 27 26 25 24 23 22 21 20) 
(19 18 17 16 15 14 13 12 11 10) 
(9 8 7 6 5 4 3 2 1 0) 

在此处查看结果https://ideone.com/Paorct 并使用此功能删除重复号码

(defun remove-duplicate (pred l)
  (cond ((null l) NIL) 
        ((funcall pred (car l)) (remove-duplicate pred (cdr l)))
        (T (cons (car l) (remove-duplicate pred (cdr l))))))

我想实现一个接收列表并随机更改其数字的函数。做一个递归函数并使用

第 n 个

函数、随机函数和

删除重复

函数,该函数必须从列表中删除与随机找到的数字相等的数字。

停止条件是列表为空;

应该使用

使用以下语句在本地存储在随机位置找到的数字的语句:

(nth (随机 (长度 l)) l)

使用

删除重复

您应该从作为递归函数中的参数传递的列表中删除随机找到并存储在本地的数字。 我有这个,但它不起作用,我试图理解算法

我的疑惑就在这里,如何实现随机列表的功能 没有重复号码

(defun shuffle-list (l)
   ;; iterate 99 times
   (dotimes (i (- (length l) 1))
    ;; store random number to n
    (let ((n (nth (random (length l)) l)))
         ;; print value of n
         (format t "~A ~%" n)
         (cond 
             ((null l) nil)
             ;; I have this but it´s not show the new list
             (t (remove-duplicate #'(lambda (x) (= x n)) l))))))

例如结果应该是

 (94 25 54 89 21 8 36 14 41 96) 
 (78 47 56 23 5 49 13 12 26 60)  
 (0 27 17 83 34 93 74 52 45 80)  
 (69 9 77 95 55 39 91 73 57 30) 
 (24 15 22 86 1 11 68 79 76 72)  
 (81 48 32 2 64 16 50 37 29 71)  
 (99 51 6 18 53 28 7 63 10 88)  
 (59 42 46 85 90 75 87 43 20 31)  
 (3 61 58 44 65 82 19 4 35 62)
 (33 70 84 40 66 38 92 67 98 97)

【问题讨论】:

  • 这个问题有点不清楚,但我认为可以挽救。我认为您的意思是 letnthrandomremove-duplicates 可以假定为给定(在 Common Lisp Hyperspec 中查找它们!),并且您应该实现一个简单的洗牌列出没有重复的内容。
  • 谢谢,你说得对,问题是缺少把函数generate-board,但我更新了项目,目标是实现一个递归函数来打乱一个列表,而不用remove-duplicate函数删除重复项跨度>
  • 其实是Common Lisp Hyperspec

标签: lisp common-lisp lispworks


【解决方案1】:

有一个内置函数remove-duplicates,其名称以“s”结尾。

remove-duplicates 采用带有布尔值的 :from-end 关键字参数来控制保留哪些重复值:列表中出现的第一个或最后一个。

请阅读Practical Common Lisp 关于let 和关于if/cond 的信息。这是一本好书!

【讨论】:

  • 感谢@zut,在阅读了let之后,我了解到它用于将操作的结果分配给像(let ((n (nth (random (length list)) list)))这样的局部变量,现在是关于if/cond 那个缺失,关于remove-duplicates,我需要使用我提到的remove-duplicate函数,接收谓词和列表,我更新代码, 如果你想看结果check result
【解决方案2】:

remove-duplicate 定义采用谓词并删除谓词为真的元素。它的行为与内置的remove-if 相同。

因此,您必须创建一个谓词函数,将列表项与保存在(let ((n (nth (random (length list)) list))) 中的n 进行比较。了解variables, lambda, and closures

【讨论】:

  • 是的,我明白了,我做了这个(dotimes (i (- (length list) 1))... 来迭代和存储 99 数字并使用函数删除重复但它不会创建一个新列表 (t (remove-duplicate #'(lambda (x) (list n) (cons n x)) list)))))),如果你想 see the result
  • 我改成这个(remove-duplicate #'(lambda (x) (= x n) (cons n x) list) 并没有显示任何内容,我认为它需要更多的东西,但我不知道
  • 使用这个例子(remove-if #'(lambda (x) (= x 10)) '(11 10 9 5 15 10 6 0))它将删除所有数字10,我将代码更新为(remove-duplicate #'(lambda (x) (= x n)) list),我认为它缺少创建新列表的部分,我尝试(list n) (cons n x)但它是不工作
  • 这可能是您正在寻找的,接近您所拥有的:(cons n (remove-duplicate #'(lambda (x) (= x n)) list)) 并且不要忘记存储它:(setf list (cons ..))
  • 该方法是递归的,所以我实现了这个(shuffle-list (setf list (cons n list))),但它不起作用,当您看到结果时,列表会变大,我需要正确的答案来关闭它
猜你喜欢
  • 2022-06-17
  • 1970-01-01
  • 2020-01-05
  • 2020-05-02
  • 1970-01-01
  • 2015-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多