2016-11-12 56 views
0

我有一個列表列表,並且想要測試所有元素是否彼此不同,即對於列表元素的所有組合,equal應該返回nil。測試列表中的所有元素是否彼此不同

E.g.

(defparameter feld '((1 0 0 5 5 0) 
        (0 0 0 0 0 0) 
        (1 1 5 5 0 0) 
        (0 1 0 1 5 5) 
        (5 5 1 0 1 0) 
        (1 0 1 0 5 5))) 

我想用減少,但據我所知只測試鄰國的平等,會做一個循環結構一樣的:

(loop for i below (length feld) 
     for j from 1 
      if (equal (nth i feld) (nth j feld)) return t) 

是否有使用標準結構的簡單方法我目前沒有看到,還是必須創建遞歸函數?

整個數據結構代表了一個「棋盤遊戲」,其中每個列表都是棋盤上的一行,而列表中的每個元素都是這個字段的值。三個數值(0,1和5)是空的,符號A和符號B.有效的板不能有兩條相同的線。這就是爲什麼我想識別這些。

基本上,它就像remove-duplicates而不刪除。在此期間,我在想是這樣的:

(defun duplicates-p (lst) 
    (cond ((null lst) '()) 
     ((member (car lst) (cdr lst)) t) 
     (t (duplicates-p (rest lst))))) 

回答

2

事情是這樣的:

(defun unique (lsts &aux (h (make-hash-table :test 'equal))) 
    (loop :for lst :in lsts 
     :never (gethash lst h) 
     :do (setf (gethash lst h) t))) 
+0

我找到'這裏finally'條款是多餘的和混亂。 – Svante

+0

儘管給定的問題並不需要,但更通用的函數會測試gethash的第二個返回值而不是第一個,這樣空列表也不會出現兩次。 – Svante

+0

@svante兩個空列表將正確評估爲'nil',因爲每個當前鍵的值都是't'。事實上,「終於」是不需要的。當我用'never'替換'if'時,我沒有想過要移除它。 – Sylwester

相關問題