2016-05-12 33 views
-2
(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)) 

出於某種原因,刪除,它的功能只是設法刪除相關的約束一切。例如,一個約束是(勃朗寧便士)。目的是刪除包含Browning和penny兩個元素的巨大組合列表中的所有列表。但是,該函數似乎刪除每個包含Browning單獨和便士的列表。我只想要將函數刪除Browning和Penny在一起的列表。

+4

你看過[我的回答](http://stackoverflow.com/a/37164868/5747548)到你以前的問題?你似乎仍然犯了同樣的錯誤,我已經指出 – jkiiski

+0

也檢查你的布爾表達式嵌套'刪除它'。 –

回答

2

讓我們先從縮進您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函數通常只需要一個參數,您(很可能)在第一個調用後會丟失右括號。

您也只是檢查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)) 
相關問題