2017-09-26 28 views
2

問題停止,這是創建一個replace/4謂詞想x與其他元素(Y)代替從第一列表中的某個元素(X),最後保存它進入最後一個參數,一個新的列表。我知道我的基本情況(?)顯然有些問題,但我似乎無法弄清楚。當我跟蹤這段代碼時,它開始正常,但在第一個列表爲空之後,它開始添加匿名變量。請憐憫我是Prolog的新手。我不知道如何從進入一個循環

replace([], _, _, []). 
replace([H|T], X, Y, N):- 
    H = X, 
    append(N, [Y], NL), 
    replace(T, X, Y, NL). 
replace([H|T], X, Y, N):- 
    H \= X, 
    append(N, [H], NL), 
    replace(T, X, Y, NL). 
+0

你追加了錯誤的方式...這應該是'追加(NL ,[Y],N)'和append(NL,[H],N)'。但那仍然是低效的,而且你根本不需要「附加/ 3」。 –

+0

我想出了確實可以做到這一切的有效方法。但我似乎無法想到一個有效的方法。 – Boomer

+0

我將它改爲'append([Y],NL,N)'和append([H],NL,N)'。它現在可以工作,但我仍然想知道更有效的方式是什麼。 – Boomer

回答

3

沒有append/3簡單更有效的解決辦法是:

replace([], _, _, []). 
replace([X|T], X, Y, [Y|T1]):-replace(T, X, Y, T1). 
replace([H|T], X, Y, [H|T1]):-dif(X,H), replace(T, X, Y, T1). 

請注意,這是更好的,而不是使用\=操作謂詞dif/2(它有更多的關係行爲:只要測試dif(X,Y).X\=Y.用X,Y未綁定變量來查看差異)。

例子:

?- replace([2,4,5,7,8,2,3,4],2,12,L). 
L = [12, 4, 5, 7, 8, 12, 3, 4] ; 
false. 

另一種解決方案將使用DCG:

replace([],_,_) -->[]. 
replace([X|T],X,Y) --> [Y],replace(T,X,Y). 
replace([H|T],X,Y) --> [H],{dif(H,X)},replace(T,X,Y). 

final_replace(In_L,X,Y,Out_L):- phrase(replace(In_L,X,Y),Out_L). 

例子:

?- final_replace([2,4,5,7,8,2,3,4],2,12,L). 
L = [12, 4, 5, 7, 8, 12, 3, 4] ; 
false. 
+0

'dif/2'太棒了,但它不是* ISO;請參閱[來自@false的此答案](https://stackoverflow.com/a/13770020/812818)。 –

+0

@DanielLyons,我的錯誤感謝! – coder

相關問題