2017-10-13 76 views
3

我想從列表A和B中刪除每個第n個元素,它們與彼此的第n個元素不相對應。因此,例如:我列出了包含[1,2,3,4,5]的列表A和包含[1,2,2,4,7]的列表B。結果應該是包含[3,5]的列表C和包含[2,7]的列表D。我想出了這一小段代碼,但它還沒有正常工作。如何使用遞歸將多個頭添加到列表中

without_doubles([], [], [_], [_]). 
without_doubles([H|T1], [H|T2], C, D):- 
    without_doubles(T1, T2, C, D). 
without_doubles([H1|T1], [H2|T2], [H1|C], [H2|D]):- 
    without_doubles(T1, T2, C, D). 

取而代之的是[3,5][2,7]的,我越來越[3,5,_G2442][2,7,_G2445]。我知道這可能很容易解決,但我似乎無法弄清楚。感謝您提前幫助我!

+1

什麼的'_'s在'without_doubles([],[],[_],[_])'幹什麼? –

+0

我個人認爲基礎案例必須描述遞歸的目標狀態。所以A和B是空的,C和D包含一些隨機變量(如'_')。 – Boomer

+1

Prolog中沒有真正的「輸入」和「輸出」。你也可以用相反的方式查詢。不幸的是,我看到很多人認爲Haskell/Prolog解釋器做了很多不可思議的事情。事實上,解釋器的工作方式非常簡單(儘管優化過程非常複雜)。下劃線只是一個匿名變量。你可以寫'without_double([],[],[A],[B])''。以及。 –

回答

4

你的第一個規則應該是:

without_doubles([], [], [], []). 

兩個,你收到了匿名變量_是你的問題的原因。

然而有一個第二個問題與您的代碼:

?- without_doubles([1,2,3,4,5],[1,2,2,4,7],L,R). 
L = [3, 5], 
R = [2, 7] ; 
L = [3, 4, 5], 
R = [2, 4, 7] ; 
L = [2, 3, 5], 
R = [2, 2, 7] ; 
L = [2, 3, 4, 5], 
R = [2, 2, 4, 7] ; 
L = [1, 3, 5], 
R = [1, 2, 7] ; 
L = [1, 3, 4, 5], 
R = [1, 2, 4, 7] ; 
L = [1, 2, 3, 5], 
R = [1, 2, 2, 7] ; 
L = [1, 2, 3, 4, 5], 
R = [1, 2, 2, 4, 7]. 

顯然,我們只想在第一個結果,而不是其他的。我們之所以得到其他的原因是因爲在你的最後一條規則中沒有說明H1H2應該是不同的。這意味着當Prolog可以應用第二條規則時,它也能夠應用最後一條規則,從而創建所有這些選擇點。

您可以通過明確地指出H1H2必須在你的最後一條規則不同的解決這個問題,使用dif/2

without_doubles([H1|T1], [H2|T2], [H1|C], [H2|D]):- 
    dif(H1, H2), 
    without_doubles(T1, T2, C, D). 

現在我們有:

?- without_doubles([1,2,3,4,5],[1,2,2,4,7],L,R). 
L = [3, 5], 
R = [2, 7] ; 
false. 
+0

謝謝你的幫助,它現在正在工作! – Boomer

3

有兩個問題與您代碼:

  1. basecase指定si ngleton列爲第三和第四個參數,而這些應該是空列表;
  2. 沒有什麼能阻止你回溯第二個條款,從而採取第三個條款。

可以解決這個問題如下:

%% no [_], but [] 
without_doubles([], [], [], []). 
without_doubles([H|T1], [H|T2], C, D):- 
    without_doubles(T1, T2, C, D). 
%% guard the fact that H1 and H2 are different 
without_doubles([H1|T1], [H2|T2], [H1|C], [H2|D]):- 
    dif(H1,H2), 
    without_doubles(T1, T2, C, D).
+0

謝謝你幫助我! – Boomer