Prolog

时间:2016-10-11 03:28:57

标签: prolog

之前尝试过,但对我来说仍然是一团糟。认为这是最长的后续,但实际上并非如此。所以用更好的例子来写它。我正在尝试编写一个Prolog谓词来比较两个字符串,看它们是否具有相同的元素并将它们打印出来(每个成员只有一次)。目前我已经写了这个,以便将字符串分成2个不同的列表,以便于检查:

但是,我无法找到正确的方法来比较这两个列表中的每个元素,无论它们在哪里。我找到了比较的方法,直到它找到一个并且它返回true,但我需要它来比较两个列表中的每个元素并输出它们。我知道它与头部有关并比较它们,然后将下一个第一个列表成员添加为新头等。但我无法找到一种方法来实现它。此外,交叉点有点做我需要的,但它给了我每个元素(甚至多个时间)。我需要它在找到匹配的元素后停止,因此它只能找到它们一次。

plates(X,Y,Mem,Num):-
    atom_chars(X,Xs),
    atom_chars(Y,Ys),
    compare_list(Xs,Ys,Mem),
    length(Mem,Num).

compare_list([], _, []).    
compare_list([H1|T1], L, R) :-
    (check_element(H1, L)
    ->R = [H1|R]
    ;R = R
    ),
    compare_list(T1, L, R).

check_element(_, []).   
check_element(X, [H|T]) :-
   X = H,
   check_element(X, T).

例1:

?-plates('111AXB','112XXX', Mem, Num).

应输出:

Mem = ['1','1','X'],
Num = 3.

例2:

?-plates('456XYZ','678ABC', Mem, Num).

应输出:

Mem = ['6'],
Num = 1.

我尝试在这里实施解决方案: PROLOG Comparing 2 lists

我的测试:

 ?- plates('ABC123','123ABC',Mem,Num).

我的输出:

Mem = [],
Num = 0.

预期:

Mem = ['A', 'B', 'C', '1', '2', '3'],
Num = 6.

但我无法以我想要的方式工作...... 任何帮助将非常感谢!

1 个答案:

答案 0 :(得分:0)

你可以这样写:

plates(X,Y,Mem,Num):-
    atom_chars(X,Xs),
    atom_chars(Y,Ys),
    inter(Xs,Ys,Mem),
    length(Mem,Num),!.

inter(_,[],[]).
inter([],_,[]).
inter([H|T],L,[H|T1]):-
          member(H,L),
          delete(H,L,L1),
          inter(T,L1,T1).
inter([H|T],L,List):- \+member(H,L),inter(T,L,List).          

delete(H,[H|T],T).
delete(H,[X|T1],[X|T]):-dif(H,X),delete(H,T1,T).

其中inter找到交集并检查第一个列表的元素是否在第二个列表中出现,然后将其添加到第三个列表并从第二个列表中删除它。一些示例:

?- plates('112XXX','111AXB', Mem, Num).
Mem = ['1', '1', 'X'],
Num = 3.

?- plates('111AXB','112XXX', Mem, Num).
Mem = ['1', '1', 'X'],
Num = 3.

?- plates('456XYZ','678ABC', Mem, Num).
Mem = ['6'],
Num = 1.

?- plates('ABC123','123ABC',Mem,Num).
Mem = ['A', 'B', 'C', '1', '2', '3'],
Num = 6.

?- plates('123ABC','345DEF',Mem,Num).
Mem = ['3'],
Num = 1.