List 序言:反向列表--can';我找不到错误
我想写一个List 序言:反向列表--can';我找不到错误,list,prolog,reverse,List,Prolog,Reverse,我想写一个reverse/2函数。这是我的代码,我无法找出错误所在 rev([]). rev([H|T],X):-rev(T,X),append(T,H,_). 输出: rev ([1,2,3,4], X). false. 当List2的元素与List1相反时,rev(?List1,?List2)为true rev(Xs, Ys) :- rev(Xs, [], Ys, Ys). rev([], Ys, Ys, []). rev([X|Xs], Rs, Ys, [_|Bound])
reverse/2
函数。这是我的代码,我无法找出错误所在
rev([]).
rev([H|T],X):-rev(T,X),append(T,H,_).
输出:
rev ([1,2,3,4], X).
false.
当List2
的元素与List1
相反时,rev(?List1,?List2)
为true
rev(Xs, Ys) :-
rev(Xs, [], Ys, Ys).
rev([], Ys, Ys, []).
rev([X|Xs], Rs, Ys, [_|Bound]) :-
rev(Xs, [X|Rs], Ys, Bound).
输出:
?- rev([1,2,3,4],X).
X = [4, 3, 2, 1].
?- rev([3,4,a,56,b,c],X).
X = [c, b, 56, a, 4, 3].
第4版的解释
待命rev([X|Xs](1),Rs(2),Ys(3),[uu124; Bound](4))
[X | Xs]
(1)
列表1,我们案例中的输入列表(我们可以调用rev(Z,[3,2,1])。
)
Rs
(2)ResultList是一个帮助列表,我们从一个空列表开始,在每次递归调用时,我们从[X|Xs](1)
推送一个成员(添加为头成员)Ys
(3)List2,输出列表(列表1的反向列表)[|Bound]
(4)-帮助列表
用于限定Ys
的长度(3)(用于迭代“Ys的长度”次)rev(Xs(5),[X|Rs](6),Ys(3),Bound(7))。
我们将头成员X
([X|Xs]
(1))推到Rs
([X|Rs]
(6))的前面,
以及迭代Ys
(Bound
(7),[\u124; Bound]
(4))的下一个成员
当rev([](9),Ys(10),Ys(3),[](12))时,递归结束。
为true
每个[X|Xs]
(1)(现在列表是空的[]
(9))成员按相反的顺序移动到Ys
(10),我们限制了Ys(3)
(使用[[u124;绑定](4)
,现在它是空的[]
(12))
请注意
append/3
-append(?List1、List2、List1AndList2)。
当H
不是List2
时,在您的代码中使用了错误的append(T,H,)
(它是列表的头成员)
append/2
和append/3
的示例用法:
?- append([[1,2],[3]],X). % append/2 - Concatenate a list of lists.
X = [1, 2, 3].
?- append([4],[5],X). % append/3 - X is the concatenation of List1 and List2
X = [4, 5].
您不应该在函子名称rev和参数列表之间放置空格。通常这会导致语法错误:
Welcome to SWI-Prolog (threaded, 64 bits, version 7.7.1)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
?- rev ([1,2,3],X).
ERROR: Syntax error: Operator expected
ERROR: rev
ERROR: ** here **
ERROR: ([1,2,3],X) .
否则,我认为rev/4解决方案的目标是双向解决方案。如果您不需要此功能,并且希望使用不留下选择点的累加器解决方案,您可以尝试:
reverse(X, Y) :-
reverse2(X, [], Y).
reverse2([], X, X).
reverse2([X|Y], Z, T) :-
reverse2(Y, [X|Z], T).
请注意,
rev([])没有任何意义。
,对于空列表,它应该是rev([],[])。
您的意思是rev([],[])。rev([H | T],X):-rev(T,R),append(R,[H],X)。
@DennisVash我指的是rev([])。作为列表为emtpy时的退出条件。为什么不起作用?@tgtrmr它从来没有叫过。。。如果要使用append实现反向,请检查Will的注释/3@tgtrmrrev([])
不工作,因为从未调用过它。它从未被调用,因为对rev
的所有调用都有两个参数,而不是一个。Prolog不支持“默认”参数。您能为rev/4
中每个参数的含义添加一些解释吗?@WillNess添加了一些解释谢谢。所以Ys是Xs的倒数,它们的长度是一样的。另外,我猜rev/4
的子句顺序对于生成用例rev(A,B)
的工作很重要。