Prolog:匹配两个列表之间的特定元素

时间:2015-10-03 19:40:47

标签: list prolog pattern-matching match

如果列表中的任何数字与其他列表中的任何数字匹配,我已经有此代码匹配。但是,我需要修改我的递归,如果在两个列表中的相同位置找到相同的数字,则返回false。

例如:

[5,3,4,6,2][3,1,2,2,7]兼容;并且[1,3,4,9,2][4,5,2,9,8]不兼容,因为这两个列表在第4位都有9位。

这是我到目前为止的代码:

common_elements([], L) :-
    fail.
common_elements([H|T], L) :-
    memberchk(H, L), !.
common_elements([H|T], L) :-
    common_elements(T, L).

当前代码的SWI-Prolog示例输入和输出:

?- common_elements([1,2,3,4],[6,7,8,9]).
false.

?- common_elements([1,2,3,6],[6,7,8,9]).
true.

1 个答案:

答案 0 :(得分:1)

与(几乎)所有带有列表处理的谓词一样,您可以将谓词拆分为两种类型的子句:

  • 基本条款:在许多情况下,这些列表处理空列表。这是例如:

    compatible([],_).
    compatible(_,[]).
    
  • 归纳条款:在这种情况下,两个列表都不为空。在这种情况下,您必须比较两个列表的 head 。如果不相等,则进行递归调用:

    compatible([HA|TA],[HB|TB]) :-
        HA \= HB,
        compatible(TA,TB).
    

    在递归调用中,您只需使用两个列表中的 tail

现在合并两个子句:

compatible([],_).
compatible(_,[]).
compatible([HA|TA],[HB|TB]) :-
    HA \= HB,
    compatible(TA,TB).

你可以使它更有效(和使用切割原子):

compatible([],_) :-
    !.
compatible(_,[]).
compatible([HA|TA],[HB|TB]) :-
    HA \= HB,
    compatible(TA,TB).

演示(swipl

?- compatible([5,3,4,6,2],[3,1,2,2,7]).
true.

?- compatible([1,3,4,9,2],[4,5,2,9,8]).
false.