List 序言:删除所有连续整数子列表
所以我遇到了这个序言问题: 给定一个线性数字列表,删除所有连续值序列 例如,List 序言:删除所有连续整数子列表,list,prolog,sublist,meta-predicate,List,Prolog,Sublist,Meta Predicate,所以我遇到了这个序言问题: 给定一个线性数字列表,删除所有连续值序列 例如,remove([1,2,4,6,7,8,10],L)将产生L=[4,10] 我成功地编写了以下代码: consecutive(N,P):- N is P-1. removeS([],[]). removeS([H],[H]). removeS([H1,H2],[]):- consecutive(H1,H2). removeS([H1,H2|T],[H1|L]):- not(consecutiv
remove([1,2,4,6,7,8,10],L)
将产生L=[4,10]
我成功地编写了以下代码:
consecutive(N,P):-
N is P-1.
removeS([],[]).
removeS([H],[H]).
removeS([H1,H2],[]):-
consecutive(H1,H2).
removeS([H1,H2|T],[H1|L]):-
not(consecutive(H1,H2)),
removeS([H2|T],L).
removeS([H1,H2,H3|T],L):-
consecutive(H1,H2),
not(consecutive(H2,H3)),
removeS([H3|T],L).
removeS([H1,H2,H3|T],L):-
consecutive(H1,H2),
consecutive(H2,H3),
removeS([H3|T],L).
它几乎适用于以下情况:
removeS([1,2,3,4,5,2,3,4,5,6,7,9,11],R). --> R = [5, 9, 11];
Here only 9 and 11 should be displayed
removeS([3,2,1,2,3,4,5,2,3,4,5,6,7,9,11],R). --> R = [3, 2, 5, 9, 11];
Here only 3,2,9,11 should appear in R
这是因为它在计算下一步时考虑了递增序列的最后一个数
我在这里做错了什么?你做的事情没有必要那么笼统(而且更复杂)
?- removeS([1,2,3],R).
R = [3] ;
false.
我引入了一个服务谓词,它“吃掉”所有连续词,并简化了逻辑,使其仅在出现两个连续词时启动,我有:
?- removeS([3,2,1,2,3,4,5,2,3,4,5,6,7,9,11],L).
L = [3, 2, 9, 11].
编辑
这是我的定义。切割可以被移除,正如你所做的那样,否定了替代方案,但我认为这只会使整体变得混乱。或者,简单地说,放下它,用once/1包装/2 top call
removeS([],[]).
removeS([A,B|T],L):- succ(A,B), eat(A,[B|T],R), !, removeS(R, L).
removeS([A|B],[A|L]) :- removeS(B,L).
eat(A,[B|T],R) :- succ(A,B), eat(B,T,R).
eat(_,T,T).
在这个答案中,我们结合使用两个s
基于、和,我们定义:
consecutives_removed(Xss, Zs) :-
split_if_adj(z_nonsucc_t, Xss, Yss),
tfilter(\[_|Xs]^(Xs=[]), Yss, Zss),
append(Zss, Zs).
示例查询(由OP给出):
这是一个很好的尝试!它没有给出您想要的答案的原因是最后一个子句的最后一行。如果
连续(H2,H3)
成功,则您不希望删除([H3 | t],L)
,因为您不想计数H3
。你只需要删除(T,L)。
@潜伏者:在应用你的“更正”后,我得到(如预期的那样)?-删除([1,2,3,4],L)。L=[4]
。你有不同的结果吗?我坚持认为缺少的是泛化…@我没有测试那个案例。我的“纠正”是必要的,但还不够。谓词显然需要更多的东西才能使其正确。我并没有声称这是一个完整的解决方案。这只是我发现的东西。我认为您的答案是在重构方向上的改进。我只是在寻找一个补丁(部分地回答了“我所拥有的东西有什么问题?”):)@潜伏者:这种方法在逻辑上是有缺陷的:删除N个连续的元素会删除检查以下元素所需的“前瞻性”!我避免发布完整的代码(5行!),希望Eugen(我同意他的是一个很好的尝试)能够对发现合适的解决方案感兴趣。尽管OP最初的方法在逻辑上并没有完全的缺陷(我提出了一个类似的、可行的解决方案),但您的解决方案更干净、更紧凑(+1)。
consecutives_removed(Xss, Zs) :-
split_if_adj(z_nonsucc_t, Xss, Yss),
tfilter(\[_|Xs]^(Xs=[]), Yss, Zss),
append(Zss, Zs).
?- consecutives_removed([1,2,4,6,7,8,10], Xs).
Xs = [4,10].
?- consecutives_removed([1,2,3,4,5,2,3,4,5,6,7,9,11], Xs).
Xs = [9,11].
?- consecutives_removed([3,2,1,2,3,4,5,2,3,4,5,6,7,9,11], Xs).
Xs = [3,2,9,11].