替换Prolog中列表中的单个元素

时间:2015-10-18 10:43:23

标签: list prolog

我获得了一个列表,一个要替换的元素以及该元素的替换。我设法为该列表中所有出现的元素执行此操作:

replace([],X,Y,[]).
replace([X|T], X, Y, Z) :-
   replace(T, X, Y, Z1),
   Z = [Y|Z1].
replace([H|T], X, Y, [H|Z]) :-
   replace(T, X, Y, Z). 

但是现在我必须只替换该元素的第一次出现。 我的思维过程写作:

replace([X|T], X, Y, Z) :-
   replace(T, X, Y, Z1), 
   Z = [Y|Z1].

是:
 如果Z[X|T],X,YZ1T的结果,则XYZ = [Y|Z1]的结果。按照相同的思考过程,我尝试编写只替换第一次出现的元素的函数,如下所示:

仅实施第一次出现的想法是从replace/4进入replace/5,如果我更换或不是这样的话,我会计算:

replace_single(L,X,Y,Z) :- 
   replace2(L,X,Y,0,Z).

replace2([],X,Y,C,[]).
replace2([X|T], X, Y, C, Z) :-
   \+ (C = 0),
   replace2(T, X, Y, C, Z1),
   Z = [X|Z1],
   C is 1.
replace2([H|T], X, Y, C, [H|Z]) :-
   replace2(T, X, Y, C, Z).

显然它不起作用,我有点迷失。有人能给我一个关于我如何思考解决问题或解决方案本身的提示吗?

3 个答案:

答案 0 :(得分:1)

我们根据replace/4append/3maplist/2定义same_length/2

replace(Xs,X,Y,Ys) :-
   same_length(Xs,Ys),
   append(Prefix,[X|Suffix],Xs),
   maplist(dif(X),Prefix),
   append(Prefix,[Y|Suffix],Ys).

示例查询:

?- replace(Xs,2,two,[1,two,3,4,5,1,2,3,4,5,1,2]).
  Xs = [1,2,3,4,5,1,2,3,4,5,1,2]
; false.

?- replace([1,2,3,4,5,1,2,3,4,5,1,2],2,two,Ys).
  Ys = [1,two,3,4,5,1,2,3,4,5,1,2]
; false.

答案 1 :(得分:1)

另一种方法是使用DCG:

rep1(X, Y, [Z|T]) --> [Z], { dif(Z, X) }, rep1(X, Y, T).
rep1(X, Y, [Y|T]) --> [X], rest(T).
rep1(_, _, []) --> [].

rest([]) --> [].
rest([H|T]) --> [H], rest(T).

| ?- phrase(rep1(a, 1, L), [a,b,c,a,d]).

L = [1,b,c,a,d] ? ;

| ?- phrase(rep1(a, 1, [x, y, 1, b]), L).

L = [x,y,1,b] ? a

L = [x,y,a,b]

您可以将谓词编写为:

replace(X, Y, L, R) :- phrase(rep1(X, Y, R), L).

答案 2 :(得分:0)

另一种方法是: -

replace(E1,L1,E2,L2) :-
same_length(L1,L2),
append(BeforeElement,[E1|AfterElement],L1),
append(BeforeElement,[E2|AfterElement],L2).

其中BeforeElement代表元素前面列表的前缀,After Element代表元素后面列表的后缀。