我想從列表中刪除第一,第二,第四和第八個元素。 我該怎麼辦? 我嘗試這樣做:如何從列表中刪除序言中的第1,第2,第4和第8個元素
del([],[]).
del([H1,H2,H3,H4|T],[H3|T]).
和它的作品,但我怎麼能做到這一點遞歸,不寫才能刪除我想要的位置8個元素?
我想從列表中刪除第一,第二,第四和第八個元素。 我該怎麼辦? 我嘗試這樣做:如何從列表中刪除序言中的第1,第2,第4和第8個元素
del([],[]).
del([H1,H2,H3,H4|T],[H3|T]).
和它的作品,但我怎麼能做到這一點遞歸,不寫才能刪除我想要的位置8個元素?
那麼......編寫一個刪除第n個元素的謂詞,然後是一個索引列表並刪除所有這些元素?
刪除第n個很簡單:
del([_|T],T,1).
del([Head|Tail],B,N) :-
K is N-1,
del(Tail,C,K),
B = [Head|C].
因爲我們知道,N不是1(否則會被使用的第一條),我們堅持前(看到B=[Head|C]
,我們沒扔Head
離開!),並做一個遞歸調用del(Tail,C,K)
確定C
與第n個刪除。
現在,listdel
,這需要索引列表:
listdelaux(A,A,[],_).
listdelaux(A,B,Indices,Level) :-
Indices = [N|IndicesTail],
K is N-Level,
del(A,X,K),
L is Level + 1,
listdelaux(X,B,IndicesTail,L).
listdel(A,B,Indices) :- listdelaux(A,B,Indices,0).
的listdelaux
謂詞有四個參數:原名單,新的列表,索引列表,以及水平,這在第一個電話應該是零。 它會刪除第一個索引;然後再調用自身在新的下一個索引,但調用它應該從新的指數減去被刪除已刪除的指標的數量:
從[a,b,c,d,e,f]
刪除[2,4]
:
[a,b,c,d,e,f] --> del(.,.,2) --> [a,c,d,e,f]
[a,c,d,e,f] --> del(.,.,3) --> [a,c,e,f]
見我們必須在第二次調用中從4中減去1。
統一是你的朋友:
delete_one_two_four_eight_elements(
[_, _, Third, _, Five, Six, Seven, _| Rest],
[Third, Five, Six, Seven| Rest]
).
如果我理解正確,原始海報想要一個遞歸解決方案,而不是枚舉每個第n個元素(大概是這樣可以使用不同的索引集),但我可能是錯的... – Jay
一般的解決方法,如果指數給出值的增加列表,也可以用DCG做:
del([C|Ns], C, Xs) --> [_], { C1 #= C + 1 }, del(Ns, C1, Xs).
del([N|Ns], C, [X|Xs]) --> [X], { N #\= C, C1 #= C + 1 }, del([N|Ns], C1, Xs).
del([], _, Xs) --> rest(Xs).
del(_, _, []) --> []. % ***
rest([]) --> [].
rest([X|T]) --> [X], rest(T).
delete_indices(Indices, List, Result) :-
phrase(del(Indices, 1, Result), List).
隨着第***
如上所述,超出列表長度的索引被忽略:
| ?- delete_indices([1,3,5,12], [a,b,c,d,e,f,g], L).
L = [b,d,f,g] ? ;
no
| ?-
如果省略***
條款,則有超過列表長度的索引的查詢會失敗,所以上面的查詢將失敗(因爲沒有12元),但與專門現有索引列表將工作:
| ?- delete_indices([1,3,5], [a,b,c,d,e,f,g], L).
L = [b,d,f,g] ? ;
no
| ?-
請注意,可以使用if_//3
來實現確定性解決方案。
我認爲答案取決於你想如何概括這個問題。 Jay的回答假設你想要一個完全一般的解決方案,在這個解決方案中你可以得到一個要刪除的元素的索引列表。 Paulo的解決方案對於一組固定的指數更符合實際。如果'n'是2的冪,第三個選項就是你想刪除元素'n'。第一和第三選項將使用遞歸,但第二個選項不需要它。那麼你想以什麼方式定義*我想要的職位*? – lurker
這四個是你想要刪除的項目的唯一指數? – repeat