之前尝试过,但对我来说仍然是一团糟。认为这是最长的后续,但实际上并非如此。所以用更好的例子来写它。我正在尝试编写一个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.
但我无法以我想要的方式工作...... 任何帮助将非常感谢!
答案 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.