簡體   English   中英

如何從prolog列表中刪除列表?

[英]How to remove a list from a list in prolog?

我想在prolog中實現以下問題:
給定L1=[1,2,3,4] and L2=[2,3,4]
調用名為remove_list(L1,L2,L)的函數將從L1中刪除L2。
所以L將是[1]。 但是如果第二個列表的元素與L1中的元素順序不同,或者更准確地說第二個元素不是第一個List的子集,則它不會刪除任何內容。
假設L1=[1,2,3,4,5] and L2=[2,3,6] or L2=[2,6] or L2=[4,3,2] will result L=[1,2,3,4,5]
任何幫助將受到高度贊賞。 提前致謝

您可以使用遞歸來構建謂詞remove_list / 3,這在處理Prolog中的列表時是一個有用的工具。

remove_list([], _, []).
remove_list([X|Tail], L2, Result):- member(X, L2), !, remove_list(Tail, L2, Result). 
remove_list([X|Tail], L2, [X|Result]):- remove_list(Tail, L2, Result).

請教:

?- remove_list([4,5,1,6,3], [1,4,7], L).
L = [5, 6, 3].

我們的想法是將原始列表“L1”中的每個元素復制到最終列表“L”,除非該元素是第二個列表“L2”的成員。
您的基本條款是您的停止條件,當您的原始列表“L1”為空時,在這種情況下忽略您的列表“L2”,結果始終是相同的空列表。 (您無法從空列表中刪除任何內容)。
你的第二個子句,如果頭部中的元素是列表“L2”的成員,則不要將列表“L1”的頭部中的元素復制到最終列表“L”,也要對謂詞進行遞歸調用。你的清單“L”的尾巴。
最后一個子句,將列表“L1”的頭部中的元素復制到最終列表“L”,並且還使用該列表的尾部“L”對謂詞進行遞歸調用。 我們在這里不需要目標成員/ 2,因為我們在前一個子句中使用了cut。

編輯:只有在您想要從“L2”列表中包含的列表“L1”中刪除項目時才應考慮此答案,無論順序如何。 要從集合“L1”中刪除子集“L2”,請使用Lurker的解決方案或其他解決方案:

remove_list(L, [], L):- !.
remove_list([X|Tail], [X|Rest], Result):- !, remove_list(Tail, Rest, Result).
remove_list([X|Tail], L2, [X|Result]):- remove_list(Tail, L2, Result).

這個新的解決方案考慮了列表“L2”中元素的順序,但不是嚴格意義上的,即,可以散布在原始列表“L1”中,這不違反“L2”作為“子集”的概念。 L1" 。

[2,4]是集合[1,2,3,4,5,6]的子集,但[2,4,7]不是:

?- remove_list([1,2,3,4,5,6], [2,4], L).
L = [1, 3, 5, 6].

?- remove_list([1,2,3,4,5,6], [4,2], L).
false.

?- remove_list([1,2,3,4,5,6], [2,4,7], L).
false.

現在,考慮到在原始集合中的任何元素都可以被刪除的情況下希望獲得原始集合而不是負面響應的事實,那么我們使用輔助謂詞:

rm_subset(L1, L2, L):-  remove_list(L1, L2, L),!.
rm_subset(L1, L2, L1).

請教:

?- rm_subset([1,2,3,4,5,6], [4,2], L).
L = [1, 2, 3, 4, 5, 6].

?- rm_subset([1,2,3,4,5,6], [2,4], L).
L = [1, 3, 5, 6].

另一種可能的解決方案,使用delete/3謂詞:

remove_elements(L, [H|T], R) :-
    delete(L, H, R1),
    remove_elements(R1, T, R).
remove_elements(L, [], L).

| ?- remove_elements([4,5,1,6,3], [1,4,7], L).

L = [5,6,3] ? ;

no
| ?-


編輯我剛剛意識到我完全誤解了這個問題。 咄。 如果你想按照規定保持“刪除”列表的順序,那么鮑里斯關於append/3的評論是正確的。 append(A, B, C)意味着如果你拿A並追加B你得到C ,保留了元素順序。

因此,要按要求重新提供解決方案:

 remove_elements(L1, L2, L) :- append(A, B, L1), append(C, L2, A), append(C, B, L). 

通常,如果您只想從另一個列表中刪除列表中的多個元素,您可以使用:

subtract(+Set, +Delete, -Result)

其中set = unorderd list可以有一些重復的元素,delete =我們要從Set中刪除的元素列表。

例如:

subtract([1,3,5,6,4,2,3], [1,2,3], R).
R = [5, 6, 4].

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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