[英]Reversing a list in Prolog
我試圖在 Prolog 中反轉列表,但我不知道如何在執行過程中刪除括號[]
。
inverser([],[]).
inverser(X,X).
inverser([T1|L1],[L2,T1]):- inverser(L1,L2).
我嘗試了 flatten méthode 但不知道如何實現它。
反轉列表的規范方法是將列表分為頭部和尾部,遞歸地反轉尾部並將頭部附加到它:
reverse( [] , [] ) .
reverse( [X|Xs] , Ys ) :- reverse(Xs,Zs), append(Zs,[X],Ys).
它簡單、優雅、純粹。 . . 並在 O( n ²) 時間內運行。 所以實際上沒有人這樣做。
反轉列表的最簡單方法可能就是這樣:
我們用一個額外的參數(在本例中是一個累加器)調用一個輔助謂詞,我們用空列表作為種子。 反轉列表就像將源列表中的每個項目添加到累加器一樣簡單。 這在 O( n ) 時間內運行。 好多了!
inverser(Xs,Ys) :- inverser(Xs,[],Ys).
inverser( [] , Ys , Ys ) .
inverser( [X|Xs] , Ts , Ys ) :- inverser(Xs,[X|Ts],Ys).
請注意,這不是對稱算法:
第一個參數 | 第二個參數 | 結果 | 筆記 |
---|---|---|---|
[a,b,c] |
是的 | Ys=[c,b,a] |
|
Xs | [a,b,c] |
Xs=[c,b,a] |
回溯進入死循環 |
[a,b,c|Xs] |
是的 | Xs=[], Ys=[c,b,a] |
回溯產生每個增加長度的列表,變量作為列表元素 |
Xs | [a,b,c|Ys] |
Xs=[c,b,a], Ys=[] |
回溯產生每個增加長度的列表,變量作為列表元素 |
Xs | 是的 | Xs=[], Ys=[] |
回溯產生每個增加長度的列表,變量作為列表元素 |
您可以通過在開始時進行一些類型檢查來解決此問題,具體取決於您想要的行為。 例如,如果兩個參數都是完全未綁定的,並且如果第一個參數是完全未綁定的,則將它們交換以防止無限遞歸。
inverser(Xs,Ys) :- var(Xs), var(Ys), !, fail. % If both args are unbound, just fail.
inverser(Xs,Ys) :- nonvar(Xs), !, inverser(Xs,[],Ys). % If the 1st arg is unbound, invoke the helper.
inverser(Xs,Ys) :- nonvar(Ys), inverser(Ys,[],Xs). % If the 2nd arg is unbound, switch the order of the arguments
inverser( [] , Ys , Ys ) .
inverser( [X|Xs] , Ts , Ys ) :- inverser(Xs,[X|Ts],Ys).
SWI Prolog 簡單地並行遍歷兩個參數,以防止無限遞歸回溯到inverser(Xs,[a,b,c])
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.