2016-09-29 67 views
0

所以我正在学习序言的过程。达到结果然后返回到初始状态

我想要做的就是改变元素的顺序,并得到新的列表作为结果。

在追踪解决方案时,我找到了正确的答案,但是一旦我到达基本案例,Prolog就会开始再次清空列表并返回空列表。

代码:

accRev([], [], _) :- !. 
accRev([], A, R) :- accRev(A, [], R), !. 
accRev([H, H2 |T], A, R):- 
    append(R, [H], R1), 
    append(A, [H2], A1), 
    accRev(T, A1, R1), !. 
accRev([H], A, R):- 
    append(R, [H], R1), 
    accRev(A, [], R1), !. 

accRevT([], [], _) :- !. 
accRevT([], A, R) :- accRev(A, [], R), !. 
accRevT([H, H2 |T], A, R):- 
    append(R, [H], R1), 
    append(A, [H2], A1), 
    accRevT(T, [H2 | A], [H | R]), !. 
accRevT([H], A, R):- 
    append(R, [H], R1), 
    accRevT(A, [], [H | R]), !. 

跟踪的图像

注意它是如何达到accRev([],[],[1,3,2,4])(这是我想R键成为,R = [1,3,2,4])

enter image description here

那么最新错误?

+1

请参阅[此答案](http://stackoverflow.com/a/15259282/1812457)。当你使用累加器时,你应该在你的递归结束子句中不要有一个匿名变量'_'。该子句通常读取'foo([],Acc,Acc).',而不是'foo([],[],_)。 – 2016-09-29 06:42:59

+2

您的代码的另一个主要问题:切割太多。你真的知道他们每个人做什么吗?你知道如果将他们离开改变程序吗? – 2016-09-29 06:44:13

+1

你想要什么作为输出 - 你的程序的目的是什么,因为“改变元素的顺序”不是很清楚...... – coder

回答

0

如果正确地理解你想做什么,你可以写:

accRev([],[]). 
    accRev([X|Y], Lout):- 
    split_list([X|Y],Z1), 
    split_list(Y,Z2), 
    accRev(Z2,Z3), 
    append(Z1,Z3,Lout). 


split_list([],[]). 
split_list([X|[]], [X]). 
split_list([X,_|T], [X|R]):-split_list(T,R). 

例子:

?- accRev([1,2,3,4],R). 
R = [1, 3, 2, 4] ; 
false. 

在你的解决方案,我觉得有些问题是由于使用过多造成的削减和accRev([], [], _)鲍里斯写道,也我认为你不需要中间名单,因为例如条款:

accRev([], [], _) :- !. 
accRev([], A, R) :- accRev(A, [], R), !. 

会导致问题,因为如果第一个列表是两个子句匹配的空列表。

相关问题