2011-11-16 60 views
2

我試圖刪除出現在Prolog中的子列表[z,z,z]之後的列表的所有成員。 f.ex removeafterZZZ([a,b,c,z,z,z,a], X) -> X = [a,b,c,z,z,z].刪除列表中出現的給定列表的成員

我有方法子表聯接給出。

% first argument is a sublist of the second argument 
    sublist(Sublist, List):- 
     join(_List1, List2, List), 
     join(Sublist,_List3, List2). 


    % we get the list in third argument by joining lists from first two arguments 
    join([], L, L). 
    join([Head | Tail1], List2, [Head | Tail3]):- 
    join(Tail1, List2, Tail3). 

所以,我一直在思考的3個可能的輸入 「選項」:

1)[]

2)類似[A,B,C],[A,B, C,Z,Z],其中輸出自動將==輸入

3)類似[A,b,C,Z,Z,Z,A]

所以我想的3個規則:

removeafterZZZ([],[]). %for empty lists 
removeafterZZZ(List,X) :=     %for lists with no [z,z,z] sublist 
     not (sublist ([z,z,z], List)) , 
     X = List. 

removeafterZZZ([H|T], X) :=   %for lists with sublist [z,z,z] 
     join(H, X, X),     %join the head of list with X 
     removeafterZZZ(T, X).   %call function again with tail 

因此,這顯然不能這樣工作,我怎麼知道我是否已經寫入z,z,z到輸出列表中?我應該使用櫃檯嗎?怎麼樣?

回答

1

如果你允許使用的append(它與序言提供的標準列表謂語),這裏有一個通用的方法來刪除一個後綴 -

% removeAfterSuff(Original List, Suffix To Remove, Result) 
removeAfterSuff(X, [], X) :- !. 
removeAfterSuff(X, Y, X) :- \+ sublist(Y,X). 
removeAfterSuff(X, Y, Z) :- append(A, B, X), append(Y, _, B), append(A,Y,Z). 

它採用了切割,所以這是一個有點難看,但否則謂詞2將給出一堆結果,如果你通過[](是啊,是紅色的,不管)。

下面是它的工作方式,如果後綴不是列表中的成員,則選項2激活且X和Z相等。否則它說「存在兩個列表,A和B可以使我的原始列表,第二個列表B,以我的後綴開頭,然後包含所有內容(我不在乎這些東西是什麼)。 A是後綴之前的所有內容,那麼我的結果是A連接到Y.「

注意,這會給你多個結果像

[a,b,z,z,z,a,b,z,z,z] 

編輯列表補充:如果您能夠接受空列表返回結果一樣

removeAfterSuff([a,b,c], [], Z). 
Z = [] 
Z = [a] 
Z = [a,b] 
Z = [a,b,c] 
可以卸下第一線
+1

他被允許使用append,除了他在OP中稱其爲「join」。 – hugomg

+0

啊,就這樣。我認爲加盟可能會祕密追加,但沒有充分考慮到這一點。 – LinearZoetrope

+0

非常感謝你的解釋!這確實解決了我的問題。 – thenet

1

我認爲你需要擔心約三例(所以三個規則...)

  1. 空單[]
  2. 名單開始[z,z,z]不以啓動
  3. 非空列表[z,z,z]

的你將如何解決這個問題的傳統語言的想法 - 你走在列表中,直到它結束或者你發現一個[z,z,z]圖案在中間。

+1

THX你的答案!因此情況1)空列表:'removeafterZZZ([],[])。 %的空列表是我的規則正確嗎?你只是得到一個空的列表。 對於其他情況。在傳統語言中,我會有一個計數器i = 0和每個z爲+1,如果z = 3則忽略列表的其餘部分。 這將解決案例2)3) 但我該如何解決這個在序言? ;) – thenet

+1

@thenet,那麼你的代碼就會出錯,我想。對於'[z,a,z,z,x]'它將返回'[z,a,z,z]',即使它不包含'[z,z,z]'。 – svick

+0

做得好,沒有給出答案逐字的幫助。 – DaveEdelstein

1

哪怕是家庭作業完全反應已經給了這麼...

remove_after([], _, []). 
remove_after([H|L], P, O) :- 
     ( append(P, _, [H|L]) 
     -> O = P 
     ; O = [H|O1], 
      remove_after(L, P, O1)).