2016-11-12 55 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

相关问题