Prolog:清单已反转-找不到错误

时间:2018-07-28 15:59:24

标签: list prolog reverse

我想编写一个reverse/2函数。这是我的代码,我无法弄清楚错误在哪里。

rev([]).
rev([H|T],X):-rev(T,X),append(T,H,_).

输出:

rev ([1,2,3,4], X).
false.

2 个答案:

答案 0 :(得分:1)

rev(?List1,?List2)

相比,true的元素以相反的顺序排列时,

List2List1

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))

  1. [X|Xs](1)-List1,在我们的例子中是输入列表(我们可以调用rev(Z,[3,2,1]).
  2. Rs(2)-ResultList是一个帮助列表,我们从一个空列表开始,在每次递归调用中,我们推(添加为头成员)来自[X|Xs](1)的成员。
  3. Ys(3)-List2,输出列表(List1的反向列表)
  4. [_|Bound](4)-HelpingList用于限制Ys(3)的长度(用于迭代“ Ys的长度”次)。

在每次递归调用rev(Xs(5), [X|Rs](6), Ys(3), Bound(7)).上,

我们将头成员X[X|Xs](1))推到Rs[X|Rs](6))的前面, 并迭代YsBound(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中使用了错误的代码。

使用List2append/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).