簡體   English   中英

在 Prolog 中反轉列表

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM