如何反向列出所有指定值并将其替换为其他值?

时间:2018-09-09 15:48:02

标签: prolog

想象一下,我们有一个列表:[1,2,2,3,4]。该问题可分为两部分:

  • 反转列表(我们应该收到[4,3,2,2,1]
  • 替换,例如所有2100,所以我们应该收到[4,3,100,100,1]

反转列表很容易,这是一个工作代码:

simple_reverse(List, Rev) :-
        simple_reverse(List, Rev, []).

simple_reverse([], L, L).
simple_reverse([H|T], L, SoFar) :-
        simple_reverse(T, L, [H|SoFar]).

但是替换元素有些麻烦。我尝试了以下方法:

reverse(a, b, List, Rev) :-
        reverse(a, b, List, Rev, []).

reverse(a, b, [], L, L).

reverse(a, b, [H|T], L, SoFar) :-
        reverse(a, b, T, L, [H|SoFar]).

reverse(a, b, [a|T], L, SoFar) :-
        reverse(a, b, T, L, [b|SoFar]).

出什么问题了?顺便说一下,我正在使用https://swish.swi-prolog.org/来运行代码。

2 个答案:

答案 0 :(得分:2)

您需要将变量放在ab谓词中,而不仅仅是reverse/4reverse/5(是原子),

reverse(A, B, List, Rev) :-
        reverse(A, B, List, Rev, []).

reverse(_, _, [], L, L).

reverse(A, B, [H|T], L, SoFar) :-
        dif(A,H),              %case where H is not A so we skip it
        reverse(A, B, T, L, [H|SoFar]).

reverse(A, B, [A|T], L, SoFar) :-
        reverse(A, B, T, L, [B|SoFar]).

答案 1 :(得分:0)

您可以将foldl与library(lambda)结合使用:

:- use_module(library(lambda)).
my_reverse(L, A, B, R) :-
    foldl([A,B] +\X^Y^Z^(dif(X, A) -> Z = [X |Y]; Z = [B|Y]), L, [],R).

示例:

?- my_reverse([1,2,2,3,4], 2, 100, R).
R = [4, 3, 100, 100, 1].