Prolog 序言:如何查找和删除最小列表元素?
我不熟悉Prolog 我需要帮助编写一个谓词来查找和删除列表中的最小元素Prolog 序言:如何查找和删除最小列表元素?,prolog,clpfd,Prolog,Clpfd,我不熟悉Prolog 我需要帮助编写一个谓词来查找和删除列表中的最小元素 多谢各位 让我帮你搜索一下 无论如何,有一个很好的谓词 ?- min_list([1,2,2,3],X). X = 1. 下面是一个如何从列表中删除某些元素的小示例(请注意,所有2s都消失了): 如果只想删除元素的第一次,请使用: 所以你的最终答案可能是这样的: delete_min(A, C) :- min_list(A, B), select(B, A, C), !. 及 同样,只需在列表上使用结构递归。
多谢各位 让我帮你搜索一下 无论如何,有一个很好的谓词
?- min_list([1,2,2,3],X).
X = 1.
下面是一个如何从列表中删除某些元素的小示例(请注意,所有2
s都消失了):
如果只想删除元素的第一次,请使用:
所以你的最终答案可能是这样的:
delete_min(A, C) :-
min_list(A, B),
select(B, A, C), !.
及
同样,只需在列表上使用结构递归。列表由节点
[H | T]
构成,即具有两个字段的复合数据结构-head,H
,tail,T
。Head是节点中保存的数据(列表元素),而T
是列表的其余部分
我们通过滚动列表找到最小元素,同时保留一个额外的数据-到目前为止看到的所有元素中的最小元素:
minimum_elt([H|T],X):- minimum_elt(T,H,X).
空列表案例没有定义-空列表没有最小元素
minimum_elt([],X,X).
如果列表中没有更多的元素,那么到目前为止我们得到的就是答案
minimum_elt([A|B],M,X):-
这里有两种情况:A
,或者其他情况:
A < M, minimum_elt(B,A,X).
minimum_elt([A|B],M,X):-
A >= M, minimum_elt(B,M,X).
A=M,最小值(B,M,X)。
没什么要说的了,这就完成了程序
编辑:除此之外,您还希望删除该元素。这改变了一切。嗯,一个明显的方法是首先找到最小elt,然后删除它。我们必须再次比较所有元素,这次是与之前找到的最小元素进行比较。我们能一次扫描完成吗 在Lisp中,我们可以使用。要从列表中删除任何元素,我们只需通过外科手术重置前一个节点的尾部指针,以指向删除后的下一个节点。然后使用这种方法,我们将扫描输入列表一次,将对前一个节点的引用保持到目前为止找到的最小元素,并在找到越来越小的元素时交换它。当我们到达列表的末尾时,我们只需通过手术移除最小的节点 但在Prolog中,我们无法重置内容。Prolog是一种一次性设置的语言。看来我们需要把名单翻两遍。。。或者,我们可以试着非常聪明地处理它,并在进行过程中构建所有可能的列表,在每次找到最小元素的新候选项时对它们进行排序
rem_min([A|B],L):-
% two possibilities: A is or isn't the minimum elt
rem_min(B,A,([A|Z],Z,Z),L).
rem_min([],A,(With,Without,Tail),L):- Tail = [],
% A is indeed the minimal element
L = Without.
rem_min([H|T],A,(With,Without,Tail),L):- H >= A, Tail=[H|Z],
rem_min(T,A,(With,Without,Z),L).
rem_min([H|T],A,(With,Without,Tail),L):- H < A, % use this H
copy_the_list(With,Tail,W2,T2), % no good - quadratic behaviour
Tail=[H|Z], T2=Z,
rem_min(T,A,(With,W2,Z),L).
copy_the_list([A|B],T,[A|C],C):- var(B), !, T=B. % fresh tail
copy_the_list([A|B],T,[A|C],T2):- copy_the_list(B,T,C,T2).
rem|min([A|B],L):-
%两种可能性:A是或不是最低elt
rem|min(B,A,([A|Z],Z,Z),L)。
rem_min([],A,(带尾,不带尾),L):-Tail=[],
%A确实是最小的元素
L=没有。
rem|min([H | T],A,(带,不带尾),L):-H>=A,Tail=[H | Z],
rem_min(T,A,(有,无,Z),L)。
rem_min([H | T],A,(有尾,无尾),L):-H
看来我们无法避免第二次,但至少我们可以避免所有多余的比较:
rem_min([A|B],L):- N=[A|_], rem_min(B,A,N,[N|Z],Z,L).
rem_min([],_A,N,L2,Z,L):- Z=[], N=[_,1], % finalize the minimal entry
scan(L2,L).
rem_min([H|T],A,N,L2,Z,L):- H >= A, Z=[H|Z2], rem_min(T,A,N,L2,Z2,L).
rem_min([H|T],A,N,L2,Z,L):- H < A, % use this H
N2=[H|_], N=[_], % finalize the non-minimal entry
Z=[N2|Z2], rem_min(T,H,N2,L2,Z2,L).
scan( [], []).
scan( [[_,1]|B],C):- !, scan(B,C). % step over the minimal element
scan( [[A]|B],[A|C]):- !, scan(B,C). % previous candidate
scan( [A|B], [A|C]):- !, scan(B,C).
rem|min([A|B],L):-N=[A|u],rem|min(B,A,N[N|Z],Z,L)。
rem_min([],_A,N,L2,Z,L):-Z=[],N=[[u,1],%完成最小条目
扫描(L2,L)。
rem|min([H|T],A,N,L2,Z,L):-H>=A,Z=[H|Z2],rem|min(T,A,N,L2,Z2,L)。
rem|min([H|T],A,N,L2,Z,L):-H
如果所有列表项都是整数,我们可以使用
我们定义zmin\u deleted/2
,
,及:
请注意,zmin_deleted/2
也适用于“其他方向”:
>不幸的是,人们很快就结束了一个他们不喜欢的问题。它可能因为没有OP进行研究的明显迹象而关闭。
A < M, minimum_elt(B,A,X).
minimum_elt([A|B],M,X):-
A >= M, minimum_elt(B,M,X).
rem_min([A|B],L):-
% two possibilities: A is or isn't the minimum elt
rem_min(B,A,([A|Z],Z,Z),L).
rem_min([],A,(With,Without,Tail),L):- Tail = [],
% A is indeed the minimal element
L = Without.
rem_min([H|T],A,(With,Without,Tail),L):- H >= A, Tail=[H|Z],
rem_min(T,A,(With,Without,Z),L).
rem_min([H|T],A,(With,Without,Tail),L):- H < A, % use this H
copy_the_list(With,Tail,W2,T2), % no good - quadratic behaviour
Tail=[H|Z], T2=Z,
rem_min(T,A,(With,W2,Z),L).
copy_the_list([A|B],T,[A|C],C):- var(B), !, T=B. % fresh tail
copy_the_list([A|B],T,[A|C],T2):- copy_the_list(B,T,C,T2).
rem_min([A|B],L):- N=[A|_], rem_min(B,A,N,[N|Z],Z,L).
rem_min([],_A,N,L2,Z,L):- Z=[], N=[_,1], % finalize the minimal entry
scan(L2,L).
rem_min([H|T],A,N,L2,Z,L):- H >= A, Z=[H|Z2], rem_min(T,A,N,L2,Z2,L).
rem_min([H|T],A,N,L2,Z,L):- H < A, % use this H
N2=[H|_], N=[_], % finalize the non-minimal entry
Z=[N2|Z2], rem_min(T,H,N2,L2,Z2,L).
scan( [], []).
scan( [[_,1]|B],C):- !, scan(B,C). % step over the minimal element
scan( [[A]|B],[A|C]):- !, scan(B,C). % previous candidate
scan( [A|B], [A|C]):- !, scan(B,C).
:- use_module(library(clpfd)).
zmin_deleted(Zs1,Zs0) :-
same_length(Zs1,[_|Zs0]),
maplist(#=<(Min),Zs1),
select(Min,Zs1,Zs0).
?- zmin_deleted([3,2,7,8],Zs).
Zs = [3,7,8]
; false.
?- zmin_deleted([3,2,7,8,2],Zs).
Zs = [3, 7,8,2]
; Zs = [3,2,7,8 ]
; false.
?- zmin_deleted(Zs,[3,2,7,8]).
_A in inf..2, Zs = [_A, 3, 2, 7, 8]
; _A in inf..2, Zs = [ 3,_A, 2, 7, 8]
; _A in inf..2, Zs = [ 3, 2,_A, 7, 8]
; _A in inf..2, Zs = [ 3, 2, 7,_A, 8]
; _A in inf..2, Zs = [ 3, 2, 7, 8,_A]
; false.