2016-09-29 92 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), !. 

會導致問題,因爲如果第一個列表是兩個子句匹配的空列表。

相關問題