2016-10-23 44 views
1

我需要創建一個規則,該規則具有輸入列表,然後一次從中獲取值2,並比較它們並創建一個具有較大值的新列表。Prolog - 爲查詢變量賦值(列表遞歸)

它需要像這樣的工作:

輸入:bigger([1,2,6,8,5], X).

OUTPUT:X = [2,6,8,8,5].

這裏是我的代碼:

%stop 
bigger([],_). 

%last element 
bigger([H1|[]],L2):- 
    append(L2, [H1], L3), 
    bigger([],L3). 

%compare first 2 
bigger([H1,H2|T], L2):- 
    (H1 > H2, 
    append(L2, [H1], L3), 
    bigger([H2|T], L3)) 
    ; 
    (H2 > H1, 
    append(L2, [H2], L3), 
    bigger([H2|T], L3)). 

如果我

更換基本情況
%stop 
bigger([],L):- 
    write(L). 

那麼我會得到這樣的輸出:

[2,6,8,8,5] 
X = [] ; 
[_G3685,2,6,8,8,5] 
X = [_G3685] ; 
[_G3685,_G3691,2,6,8,8,5] 
X = [_G3685, _G3691] ; 
[_G3685,_G3691,_G3697,2,6,8,8,5] 
X = [_G3685, _G3691, _G3697] 
. 

我可以看到,當它達到基本情況技術上的第二個變量具有正確的價值的。但隨後它統一爲一個空白列表。不僅如此,它還會繼續添加未知元素。

我該如何處理?

回答

1

有些事情需要改變。例如,子句:這與第bigger([],_).'_'比賽與任何匹配

bigger([H1|[]],L2):- 
    append(L2, [H1], L3), 
    bigger([],L3). 

調用更大([],L3),所以這給你的未知元素。這不是很好的主意TI採用追加,但它會更好地使用模式匹配,如:

bigger([],[]). 
bigger([H],[H]). 
bigger([H1,H2|T], [X|T1]):- 
    (H1 > H2-> 
     X=H1, 
     bigger([H2|T], T1) 
    ;H2 > H1-> 
     X=H2, 
     bigger([H2|T],T1)). 

這裏你實例在每一個遞歸調用輸出列表L3的一個元素,並做休息,直到它同有一個元素。條款bigger([],[]).僅當輸入爲空列表時纔有用。當輸入不爲空時,當一個元素已經離開列表時,遞歸停止。 if-else語句最好使用->

結果:

?- bigger([1,2,6,8,5], X). 
X = [2, 6, 8, 8, 5] ; 
false. 
+0

這工作,謝謝。但是有幾件事讓我感到困惑。 如何做大([H],[H])。完全停止遞歸?這意味着這兩個變量在列表中只有一個元素,對吧?我知道第一個輸入列表只剩下一個(因爲我們在遞歸中使它更小),但是不是第二個輸入列表(X)變大了嗎?它不應該有多個元素? – PadaKatel

+0

我們跟輸入一樣,注意輸出列表也越來越小,當輸入中有一個元素時,我們強制它有一個元素。輸出列表越來越小,因爲它是[X | T1],我們調用更大([H2 | T],T1),因此它在每個遞歸中都變小了一個元素。 – coder

+0

好吧,我想我已經開始明白了。非常有趣的是,我非常反感地看着它,試圖添加到列表中,但是實際上我們需要的工作方式與輸入列表相同。謝謝。 – PadaKatel