2016-05-23 23 views
3

相同的元素,我有兩個字符表工作,我要檢查,如果他們有相同的元素,除了在同一個位置,就像這樣:序言 - 檢查兩個列表,除了一個

compare([L1,L2,L3,L4],[W1,W2,W3,W4]) :- 
((W1 \= L1, W2 = L2, W3 = L3, W4 = L4); 
(W1 = L1, W2 \= L2, W3 = L3, W4 = L4); 
(W1 = L1, W2 = L2, W3 \= L3, W4 = L4); 
(W1 = L1, W2 = L2, W3 = L3, W4 \= L4)). 

這是工作,但有一個簡化的方法?

謝謝。

回答

3

即使您的解決方案有效,它也不是很乾淨也不可重複使用,因爲它只適用於長度爲4的列表。讓我們嘗試定義一個適用於任何大小列表的遞歸謂詞。

當一次查看兩個列表中的一個元素時,實際上只有兩種情況需要考慮:元素是相同的還是不相同的。

如果它們相同,則意味着這兩個列表的其餘部分必須只有一個不同的元素才能成功。這正是我們首先寫的謂詞!

compare([H|T1], [H|T2]) :- compare(T1, T2). 

現在是第二種情況。如果列表的第一個元素是不同的,那麼這兩個名單的其餘部分必須是完全一樣的(正如我們已經遇到了不同的元素

compare([H1|T1], [H2|T1]) :- H1 \= H2. 

在那裏,這一切!現在,你可能會注意到輸出如這樣的:

這是因爲還有一個選擇點開:第一個子句匹配的第一要素,但第二句話沒有考慮然而,在這種情況下,雖然,我們知道這兩個條款所以我們可以添加一個剪輯(!),以確保沒有選擇點。

這也可以讓我們簡化第二次關閉:如果我們達到了這一點,我們知道第一個元素是不一樣的,所以沒有必要再次檢查。

全部放在一起,代碼變爲:

compare([H|T1], [H|T2]) :- !, compare(T1, T2). 
compare([_|T], [_|T]). 
+1

這正是我需要的!謝謝! – KonaKona

+1

工作正常(+1),但有一個警告:兩個列表必須是無變量的,否則代碼的行爲是非單調的... – repeat