2013-04-02 272 views
3

我想編寫一個函數,它需要兩個參數列表並檢查第一個元素中是否包含第二個元素(元素的順序無關緊要)。該函數也將檢查兩個列表是否具有相同的長度(兩個列表不能有重複的元素),因爲如果不是,那麼函數將返回nill/false。LISP:如何測試兩個列表是否具有相同的元素?

例如: (ABCDEF)和(BEAFDC)具有相同的元件 (零)和(無)具有相同的元件

(ABCDEF)和(ABCDEFG)不具有相同的元件

問題是我知道只有一些基本的命令,我可以使用那些。這是幾乎所有我認識的命令:

CAR, CDR, LENGTH, NULL, MEMBER, NOT, AND, OR, NOT, MAPCAR, APPLY, DO, SETQ, LET 

我寫了下面的函數到現在爲止,但我不知道如何檢查重複的成員,它不適合所有列表正常的工作,我想檢查:

(defun same-elem-p (lst1 lst2) 
    (cond ((not (null lst1)) 
     (cond ((member (car lst1) lst2) 
       (same-elem-p (cdr lst1) lst2)) 
       (t nil))) 
     (t t))) 

我希望我解釋得很好的問題。

回答

6

當列表中包含另一個可以定義返回true函數:

(defun member (x liste) 
    (cond 
     ((null liste)()) 
     ((equal (car liste) x) liste) 
     (t (member x (cdr liste))))) 

(defun inclus (liste1 liste2) 
    (cond 
     ((null liste1) t) 
     ((member (car liste1) liste2)(inclus (cdr liste1) liste2)) 
     (t()))) 

然後用它來確定這兩個列表是否相等:

(defun compare (liste1 liste2) 
    (if ((and (inclus liste1 liste2) (inclus liste2 liste1))) 
     (print "the 2 lists are equivalent") 
     (print "the 2 lists aren't equivalent"))) 
+1

感謝您的回答。是否有可能只用一個函數來編寫所有這些?我想知道你爲什麼寫成員函數;它在LISP中還不存在? – seby598

+0

當然有一種方法,但我認爲這不會很簡單!和是的成員函數已經存在,但我忘了。我沒有在LISP上編程已經有一年多的時間了。 – Kira

2

收件它映射超過list1的和List1中

  1. 發現它在list2中的每個元件的功能。如果它不在list2中,則失敗。
  2. 否則從列表2中刪除
0

如果你的元素是數字,或者如果你有一個體面的比較元素(在這種情況下,這將是字母順序),你可以簡化對這兩個列表使用'sort'過程,然後檢查它們是否相同。

從理論上講,對整個操作的複雜性將約爲O(N日誌(N))(因爲Lisp實現「排序」是非常好的)。至於Hedi的回答,複雜性會像O(N²/ 2)那樣(因爲'成員'將被稱爲N次,每次呼叫的平均時間爲(N/2))。

0

處理列表作爲一組,如果你可以像使用多個命令:如果交集不是空集,以及性差異

(defun equal-lists (list1 list2) 
(and (eq (null (intersection list1 list2)) nil) 
(null (set-difference list1 list2)))) 

然後:

INTERSECTION SET-DIFFERENCE EQ 

您可以定義此功能是空的,set1等於set2。

1

兩個列表具有相同的元素時,在一個列表中的每個元素是其他列表中的一員,並且反之亦然。假設你可以使用every功能,快速的方法來測試,這是如下:

(defun same-elements (lst1 lst2) 
    (and (= (length lst1) (length lst2)) 
     (every #'(lambda (x) (member x lst2)) 
       lst1) 
     (every #'(lambda (x) (member x lst1)) 
       lst2))) 

例如:

CL-USER> (same-elements '(a b c) '(c a b)) 
T 

注意,該代碼將不會處理各種情況。例如,當在兩個列表中重複兩個不同的元素時,它將返回T,如在(a b b c)(a a b c)中那樣。但是,大多數情況下,它的工作是完成的。

0
(defun same (a b) 
`(cond 
((null a)'same) 
((member(car a) b) (same(cdr a) b)) 
(t'nosame))) 

(defun entre () 
(let((a) (b)) 
(princ " list a : ") (setq a (read)) 
(princ " list b : ") (setq b (read)) 
(if (= (length a) (length b)) (same a b) 'nosame))) 
+0

請編輯更多信息。僅限代碼和「嘗試這個」的答案是不鼓勵的,因爲它們不包含可搜索的內容,也不解釋爲什麼有人應該「嘗試這個」。 – abarisone

0

兩個列表包含相同的元素,如果他們是彼此的子集。

(defun same-elements (l1 l2) 
    (and (subsetp l1 l2) (subsetp l2 l1))) 
相關問題