如何解决prolog中的交换函数,无限循环
我试图在 prolog
中创建一个交换函数,但我最终得到了一个 infinite loop
,我尝试使用 trace()
调试它
这个函数的一个例子是 swap(4,3,["You","Are","Awesome","thank","You"],SwappedList)
输出为
[“你”、“是”、“谢谢”、“真棒”、“你”]
在跟踪输出中,它显示问题在于删除,因为它是 failing
和 redoes
split
/* Getting the nth element of the list*/
n_thelement(1,[Head|_],Head).
n_thelement(N,[_|Tail],Item):-
NewN is N-1,n_thelement(NewN,Tail,Item).
/* Deleting the element of the desired Nth element*/
delete(X,[X|Tail],Tail).
delete(X,[Head|Tail],[Head|Item]):-
delete(X,Item).
/* Adding the deleted element to the beginning of the list*/
append([],Element,Element).
append([Head],[Head|Element]).
swap(X,X,List,List).
swap(X,Y,NList):-
n_thelement(X,Num1),n_thelement(Y,Num2),split(X,B1,A1),delete(Num1,A1,L1),append([Num2],L1,NList1),append(B1,NList1,NList2),split(Y,NList2,B2,A2),delete(Num2,A2,L2),append([Num1],L2,NList3),append(B2,NList3,NList).
split(1,Head,Tail).
split(N,[Old_List|New_List],Old_List,New_List):-
NewN is N -1,split(NewN,_,New_List).
解决方法
如果我正确理解您的问题陈述,将索引分配给列表 M 和 N,使得 M
我首先将索引设为零相关而不是 1 相关,因为这会使数学更容易一些。
因此,您想将列表分成 5 部分,其中 3 个本身是任意长度的列表,其中两个是要交换的列表条目:
-
As
:列表的导入前缀。它的长度为 M。 -
B
:要交换的第一个项目。 -
Cs
:列表的中间部分。它的长度为 N - (M+1)。 -
D
:要交换的第二项。 -
Es
:列表的后缀/余数。长度不限。
append/3
对列表的解构和重建很有用,使实际的交换变得容易。您有 3 个案例。
-
首先,两个索引相同的特殊情况,在这种情况下,没有工作要做:
swap( M,M,Ls,Ls ).
-
其次,索引乱序的情况,在这种情况下,我们只是递归地交换它们以将它们排序:
swap( M,N,Rs ) :- M > N,swap(N,Rs).
-
三、一般情况:
swap( M,Rs ) :- % if the 2 indices differ M < N,% - and are in order M >= 0,% - and M is greater than or equal to zero N >= 0,% - and N is greater than or equal to zero X is N - (M+1),% - compute the length of the middle segment length( As,M ),% - construct an empty,unbound list of length M,the length of the prefix length( Cs,X ),% - and construct an empty,unbound list of that length append( As,[B|T1],Ls),% - get the prefix (As) and the first item (B) to be swapped append( Cs,[D|Es],T1),% - get the middle segment (Cs),the second item (D) to be swapped,and the suffix (Es) append( As,[D|Cs],T2),% - concatenate As,D,and Cs,then... append( T2,[B|Es],Rs ) % - concatenate that with B and the suffix . % Easy!
您可以定义一个谓词来替换列表中的i项:
replace(Index,[Old|Rest],[New|Rest],Old,New) :- Index == 0,!.
replace(Index,[First|Rest],[First|NewRest],New) :-
Index > 0,Previous is Index - 1,replace(Previous,Rest,NewRest,New).
示例:
?- replace(1,[a,b,c,d,e],List1,Old1,x).
List1 = [a,x,Old1 = b.
?- replace(1,New1).
List1 = [a,New1,Old1 = b.
?- replace(4,List2,Old2,New2).
List2 = [a,New2],Old2 = e.
然后,使用这个谓词,你可以定义:
swap(I,J,OldList,NewList) :-
replace(I,List,X,Y),replace(J,NewList,Y,X).
示例:
?- swap(3,2,["You","Are","Awesome","thank","You"],L).
L = ["You","You"].
?- swap(1,4,L).
L = [a,e,b].
?- swap(0,3,L).
L = [d,a,e].
?- swap(1,L).
L = [b,e].
?- swap(2,e].
?- swap(3,9,L).
false.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。