我获得了一个列表,一个要替换的元素以及该元素的替换。我设法为该列表中所有出现的元素执行此操作:
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,Y
,Z1
和T
的结果,则XY
是Z = [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).
显然它不起作用,我有点迷失。有人能给我一个关于我如何思考解决问题或解决方案本身的提示吗?
答案 0 :(得分:1)
我们根据replace/4
,append/3
,maplist/2
和prolog-dif定义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代表元素后面列表的后缀。