[英]Removing consecutive elements from a list in Prolog
到目前為止,我嘗試了三個單獨的函數,其中一個是第一個調用 function,另外兩個決定是否將 append 元素傳遞給我們的結果列表,如果它與列表的頭部不匹配。 遞歸使我感到困惑,因為它使許多其他人感到困惑,所以在這里的某個地方我有一個無限循環,導致堆棧溢出。 但是我不確定很多 prolog 概念(或語法),所以我很困惑我哪里出錯了。 感謝您的幫助!
append( [X | Y], Z, [X | W]) :- append( Y, Z, W).
remove([], []).
remove([H|T], X) :-
append(X, [H], X),
remove(T, H, X),
!.
remove([Y|T], Y, X):-
remove(T, Y, X),
!.
remove([H|T], Y, X):-
append(X,[H], X),
remove(T,Y,X),
!.```
嗯...首先, Prolog 沒有“功能”:它有predicates 。
如果我理解您的問題陳述,您想“從列表中刪除連續元素”,我理解這意味着“將相同元素的運行折疊為單個值”,因此列表如下:
[a,b,b,b,,c,c,d,e,e,e,e]
減少到
[a,b,c,d,e]
假設是這種情況,您不需要(或不想要) append/3
。 總體方案是
像這樣:
remove( [] , [] ) .
remove( [X|Xs] , Ys ) :- remove(Xs,Ts), try_add(X,Ts,Ys) .
try_add/3
負責決定是否在返回列表中添加/添加一個項目。 它也是微不足道的:
X
X
:
X
,X
添加到返回的列表中try_add( X , [] , [X] ) .
try_add( X , [T|Ts] , [T|Ts] ) :- X = T.
try_add( X , [T|Ts] , [X,T|Ts] ) :- X \= T.
將所有內容放在一起,您會得到:
remove( [] , [] ) .
remove( [X|Xs] , Ys ) :- remove(Xs,Ts), try_add(X,Ts,Ys) .
try_add( X , [] , [X] ) .
try_add( X , [T|Ts] , [T|Ts] ) :- X = T.
try_add( X , [T|Ts] , [X,T|Ts] ) :- X \= T.
這在 O(n) 時間和空間中運行。 它的缺點是它不是尾遞歸的,這意味着給定一個足夠長的列表,它會使你的程序因堆棧溢出而崩潰。
另一種尾遞歸方法——在 O(n) 時間和 O(1) 空間中運行——是這樣的:
remove( [] , [] ) .
remove( [X|Xs] , Ys ) :- remove(Xs, [X], Ts ), reverse(Ts,Ys) .
remove( [] , Ys , Ys ) .
remove( [X|Xs] , [T|Ts] , Ys ) :- X = T , remove( Xs , [X|Ts] , Ys ) .
remove( [X|Xs] , [T|Ts] , Ys ) :- X \= T , remove( Xs ,[X,T|Ts] , Ys ) .
它的缺點是它以相反的順序構建返回列表,因此需要通過reverse/2
進行另一次遍歷才能將事物以正確的順序放回原處。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.