我想编写一个reverse/2
函数。这是我的代码,我无法弄清楚错误在哪里。
rev([]).
rev([H|T],X):-rev(T,X),append(T,H,_).
输出:
rev ([1,2,3,4], X).
false.
答案 0 :(得分:1)
rev(?List1,?List2)
相比,true
的元素以相反的顺序排列时, List2
是List1
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].
rev/4
的解释
通话中rev([X|Xs](1), Rs(2), Ys(3), [_|Bound](4))
[X|Xs]
(1)-List1
,在我们的例子中是输入列表(我们可以调用rev(Z,[3,2,1]).
)Rs
(2)-ResultList
是一个帮助列表,我们从一个空列表开始,在每次递归调用中,我们推(添加为头成员)来自[X|Xs](1)
的成员。 Ys
(3)-List2
,输出列表(List1
的反向列表)[_|Bound]
(4)-HelpingList
用于限制Ys
(3)的长度(用于迭代“ Ys
的长度”次)。在每次递归调用rev(Xs(5), [X|Rs](6), Ys(3), Bound(7)).
上,
我们将头成员X
([X|Xs]
(1))推到Rs
([X|Rs]
(6))的前面,
并迭代Ys
(Bound
(7),[_|Bound]
(4))的下一个成员。
当rev([](9), Ys(10), Ys(3), [](12)).
为true
时,递归结束。
每个[X|Xs]
(1)(现在列表为空的[]
(9))成员以相反的顺序移至Ys
(10),我们限制了{{1 }}(使用Ys(3)
,现在为空的[_|Bound](4)
(12))。
请注意,[]
-append/3
append(?List1, ?List2, ?List1AndList2).
不是append(T,H,_)
(它是列表的头成员)时,在您的代码H
中使用了错误的代码。
使用List2
和append/2
的示例:
append/3
答案 1 :(得分:0)
您不应在函子名称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).