【问题标题】:How to remove elements a list within a list that contains two elements that you don't want?如何删除列表中包含您不想要的两个元素的列表中的元素?
【发布时间】:2016-05-12 15:55:36
【问题描述】:
(defun combinations (&rest lists) (if (car lists) (mapcan (lambda (in-val) (mapcar (lambda (out-val) (cons out-val in-val)) (car lists))) (apply #'combinations (cdr lists))) (list nil)))

这个函数可以组合任意数量的列表。

(defun main()
  (setq m-list (combinations '(Blacket Bluet Browning Greenfield Whitehall) '(four-leaf-clover penny rabbit-foot ribbon silver-dollar) '(center-field first-base right-field short-stop third-base)))

  (setq constraints  (list '(Browning penny) '(Browning silver-dollar) '(Browning right-field) '(Browning center-field) '(Bluet center-field) '(Bluet right-field) '(Greenfield first-base) '(Greenfield short-stop)
    '(Greenfield third-base) '(Whitehall center-field) '(Whitehall right-field) '(Greenfield four-leaf-clover) '(Greenfield penny) '(Whitehall four-leaf-clover) '(Whitehall penny) 
    '(Blacket four-leaf-clover) '(Blacket penny) '(Blacket first-base) '(Blacket third-base) '(Blacket ribbon) '(Bluet ribbon) '(center-field rabbit-foot)))
  (loop  
    (print m-list)
    (setq n-constraint (car constraints))
    (setq m-list (remove-it m-list n-constraint))
    (setq constraints (cdr constraints))
    (when (null constraints) (return m-list))))

主函数创建两个列表,一个包含所有可能的球员、魅力和位置组合的列表,以及一个约束列表,其中每个约束列表中的两个变量不能在一起。然后,我创建了一个循环,以便在每次迭代时采用一个约束,并从组合的主列表中删除与约束所说的不应该存在的组合。

(defun remove-it (x y) 
    (if (and (not (eq (find (nth 0 y) (car x)) nil) (not (eq (find (nth 1 y)(car x)) nil)))) (setq x (remove (car x) x :test #'equal)))
    (return x))

由于某种原因,remove-it 函数只能删除与约束相关的所有内容。例如,约束是 (Browning penny)。目的是删除包含 Browning 和 penny 这两个元素的海量组合列表中的任何列表。但是,该函数似乎会分别删除包含 Browning 和 penny 的每个列表。我只希望函数删除同时包含 Browning 和 Penny 的列表。

【问题讨论】:

  • 您是否阅读了my answer 的上一个问题?你似乎仍然在犯我已经指出的错误。
  • 还要检查你的布尔表达式在remove-it中的嵌套。

标签: list loops lisp common-lisp


【解决方案1】:

让我们从缩进 remove-it 函数开始:

(defun remove-it (x y) 
  (if (and (not (eq (find (nth 0 y) (car x)) nil)
                (not (eq (find (nth 1 y)(car x)) nil))))
      (setq x (remove (car x) x :test #'equal)))
  (return x))

这是相当荒谬的,就像函数一样。 not 函数通常只接受一个参数,您(很可能)在第一次 not 调用之后缺少右括号。

您也只检查了x 的第一个元素,所以如果没问题,您就不会检查列表的其余部分。

您的变量名称不太清楚(“x”和“y”实际上是什么意思)。

您不需要显式返回,只需将 x 作为最后的单个表达式即可。

一个可能更好的解决方案可能是(基于我对您实际想要做的事情的理解,即“收集所有没有两个被禁止组合的组合):

(defun remove-constrained-combinations (combinations constraint-1 constraint-2)
  (loop for combo in combinations
        unless (and (member constraint-1 combinations)
                    (member constraint-2 combinations)
        collect combo))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多