有人可以帮帮我吗?我需要在prolog中解决这个问题而且我不知道如何......
"给出一个整数列表。删除由reduce元素组成的所有子列表。"
答案 0 :(得分:3)
我们分三个步骤删除降序子列表:
分开减少和减少部分(使用
splitlistIfAdj/3
和(#=<)/3
)
?- splitlistIfAdj(#=<,[ 1 , 2 , 3 , 4,3,2,1 , 2 , 3 , 4,3,2,1 , 2 ],Xs1).
Xs1 = [[1],[2],[3],[4,3,2,1],[2],[3],[4,3,2,1],[2]].
排除非单身人士名单(使用tfilter/3
,Prolog lambdas和(=)/3
)
?- tfilter(\[_|T]^(T=[]),[[1],[2],[3],[4,3,2,1],[2],[3],[4,3,2,1],[2]],Xs2).
Xs2 = [[1],[2],[3], [2],[3], [2]].
将单件列表映射到项目(使用maplist/3
和Prolog lambdas)
?- maplist(\[H|_]^H^true,[[1],[2],[3],[2],[3],[2]],Xs).
Xs = [ 1 , 2 , 3 , 2 , 3 , 2 ].
让我们把它放在一起!
:- use_module(library(clpfd)).
:- use_module(library(lambda)).
descending_removed(Xs0,Xs) :-
splitlistIfAdj(#=<,Xs0,Xs1),
tfilter(\[_|T]^(T=[]),Xs1,Xs2),
maplist(\[H|_]^H^true,Xs2,Xs).
以下是一些问题:
?- descending_removed([1,2,3,4,3,2,1,2,3,4,3,2,1,2],Xs).
Xs = [1,2,3,2,3,2].
?- descending_removed([4,3,2,1,0],Xs).
Xs = [].
?- descending_removed([1,2,3,4],Xs).
Xs = [1,2,3,4].
?- descending_removed([1,2,3, 4,3,3,2,2,1],Xs).
Xs = [1,2,3].
?- descending_removed([1,2,3,4,4,3,3,2,2,1],Xs).
Xs = [1,2,3,4].
答案 1 :(得分:3)
我们可以使用this answer代替tfilter/3
和maplist/3
改进tchoose/3
,删除两个步骤中的降序子列表 - 而不是三个:
分开减少和不减少的部分(使用splitlistIfAdj/3
和(#=<)/3
)
?- splitlistIfAdj(#=<,[ 1 , 2 , 3 , 4,3,2,1 , 2 , 3 , 4,3,2,1 , 2 ],Xs1).
Xs1 = [[1],[2],[3],[4,3,2,1],[2],[3],[4,3,2,1],[2]].
过滤单件列表并映射到项目(使用tchoose/3
,Prolog lambdas和(=)/3
)
?- tchoose(\[H|T]^H^(T=[]),[[1],[2],[3],[4,3,2,1],[2],[3],[4,3,2,1],[2]],Xs).
Xs = [ 1 , 2 , 3 , 2 , 3 , 2 ].
让我们把它放在一起!
:- use_module(library(clpfd)).
:- use_module(library(lambda)).
descending_removed(Xs0,Xs) :-
splitlistIfAdj(#=<,Xs0,Xs1),
tchoose(\[H|T]^H^(T=[]),Xs1,Xs).
相同的查询,相同的结果:
?- descending_removed([1,2,3,4,3,2,1,2,3,4,3,2,1,2],Xs).
Xs = [1,2,3,2,3,2].
?- descending_removed([4,3,2,1,0],Xs).
Xs = [].
?- descending_removed([1,2,3,4],Xs).
Xs = [1,2,3,4].
?- descending_removed([1,2,3, 4,3,3,2,2,1],Xs).
Xs = [1,2,3].
?- descending_removed([1,2,3,4,4,3,3,2,2,1],Xs).
Xs = [1,2,3,4].
答案 2 :(得分:2)
让我们从一些数字样本列表开始:
1 2 3 4 3 2 1 2 3 4 3 2 1 2
在删除所有递减的子列表后,我们应该
1 2 3 2 3 2
怎么可以这样做?我建议浏览列表并观察在查看数字组时如何生成“输出”:
A B C
1 2 -> output 1
1 2 3 -> output 2
2 3 4 -> output 3
3 4 3 -> output none
4 3 2 -> output none
3 2 1 -> output none
2 1 2 -> output none
1 2 3 -> output 2
2 3 4 -> output 3
3 4 3 -> output none
4 3 2 -> output none
3 2 1 -> output none
2 1 2 -> output none
1 2 -> output 2
答案 3 :(得分:1)
(使用与之前答案相同的名称和测试):
descending_removed(L,R) :- dr(a,L,R).
dr(_,[],[]).
dr(DIR,[A|Q],R) :-
( [B|_]=Q, A>B ->
dr(d,Q,R)
;
dr(a,Q,T), ( DIR=a -> R=[A|T]; R=T )
).
验证
test :-
descending_removed([1,2,3,4,3,2,1,2,3,4,3,2,1,2],[1,2,3,2,3,2]),
descending_removed([4,3,2,1,0],[]),
descending_removed([1,2,3,4],[1,2,3,4]),
descending_removed([1,2,3,4,3,3,2,2,1],[1,2,3]),
descending_removed([1,2,3,4,4,3,3,2,2,1],[1,2,3,4]),
descending_removed([1],[1]).
给出以下结果:
[debug] ?- test.
true ;
false.
如果我们想要覆盖两个连续相等值的情况,并且解释它们不会改变曲线趋势,我们可以定义:
descending_removed(L,R) :- dr(a,L,R).
dr(_,[],[]).
dr(DIR,[A|Q],R) :-
( [B|_]=Q, A>B ->
dr(d,Q,R)
; [B|_]=Q, A=B ->
dr(DIR,Q,T), ( DIR=a -> R=[A|T]; R=T )
;
dr(a,Q,T), ( DIR=a -> R=[A|T]; R=T )
).
产生以下答案:
descending_removed([1,2,2,2,3,4,3,3,2,2,1],R).
R = [1, 2, 2, 2, 3] ;
false
descending_removed([1,2,3,3,2,4,3,3,2,2,5],R).
R = [1, 2, 3, 5]
false