我想从列表中删除第一,第二,第四和第八个元素。 我该怎么办? 我尝试这样做:如何从列表中删除序言中的第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