2017-09-26 29 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

相关问题