请问有人能帮我吗?我需要用Prolog解决这个问题,但我不知道该如何处理...
"给定一个整数列表。删除由下降元素组成的所有子列表。"
separate decreasing and non-decreasing parts (using
splitlistIfAdj/3
and (#=<)/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]].
exclude non-singleton lists (using tfilter/3
, Prolog lambdas, and (=)/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]].
map singleton lists to items (using maplist/3
and 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].
我们可以通过使用tchoose/3
而不是tfilter/3
和maplist/3
,在两个步骤中移除降序子列表,来改进这个答案:
separate decreasing and non-decreasing parts (using splitlistIfAdj/3
and (#=<)/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]].
filter singleton lists and map to items (using tchoose/3
, Prolog lambdas, and (=)/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].
让我们从一些数字列表的样例开始:
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
remove_dec([], []).
remove_dec(Input, Output) :-
min_list(Input, Min),
remove_dec0([ Min | Input ], Output).
remove_dec0([ A, B, C | Input], [ B | Output ]) :-
A =< B, B =< C,
remove_dec0([ B, C | Input], Output).
remove_dec0([ _, B, C | Input], Output) :-
remove_dec0([ B, C | Input], Output).
remove_dec0([A, B], [B]) :-
A =< B.
remove_dec0([A, B], []) :-
A > B.
样例输入和输出:
?- remove_dec([1,2,3,4,3,2,1,2,3,4,3,2,1,2],R).
R = [1, 2, 3, 2, 3, 2] .
?- remove_dec([4,3,2,1,0],R).
R = [] ;
false.
?- remove_dec([1,2,3,4],R).
R = [1, 2, 3, 4] .
once(A > B;B > C)
替换A =< B, B =< C
吗?我已经检查过了,结果会出现错误。 - Grzegorz Adam Kowalskiremove_dec0([ _, B, C | Input], Output) :- remove_dec0([ B, C | Input], Output).
最好改成:remove_dec0([A,B,C|Input],Output) :- once(A > B;B > C), remove_dec0([B,C|Input],Output).
这样这个子句和它上面的子句就可以互相排斥了(在该层级上不使用剪枝)。 - repeat关于(使用与之前回答中相同的名称和测试):
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