【问题标题】:Prolog - Cartesian product calculatorProlog - 笛卡尔积计算器
【发布时间】:2017-03-07 19:06:21
【问题描述】:

我需要为 Prolog 创建一个笛卡尔积计算器。它应该像这样工作:

输入:product([1,2,3], [a,b], X).

输出:X = [[1,a],[2,a],[3,a],[1,b],[2,b],[3,b]].

我知道网上有例子,但我想自己写点东西。

这是我的代码,我认为它非常接近,但由于某种原因它并不完全有效。有什么想法吗,伙计们?

% call new with 4 parameters (so we can keep List1 in memory)
product(L1,L2,L3):- product(L1,L2,L3,L1).

% stop when both List1 and List2 are empty
product([], [], [], []).

% first list is empty, recreate it and work it again with the next element of second list (and shorten memory)
product([], [_|T2], List3, [H4|T4]):-
    product([H4|T4], T2, List3, T4).

%go through first list and always first element of second list to our answer
product([H1|T1], [H2|T2], [[H1,H2]|T3], List4):-
    product(T1, [H2|T2], T3, List4).

【问题讨论】:

标签: list recursion prolog cartesian-product


【解决方案1】:

在 SWI-Prolog 中,还可以使用 findall/3member/2 谓词生成笛卡尔积:

:- initialization(main).
:- set_prolog_flag(double_quotes, chars).

main :-
    product([1,2,3], [a,b], X),
    writeln(X).

product(A,B,C) :-
    findall([X,Y],(member(X,A),member(Y,B)),C).

这个程序打印[[1,a],[1,b],[2,a],[2,b],[3,a],[3,b]]

【讨论】:

    【解决方案2】:

    正如 Coder (+1) 所说,您应该将终端子句从

    product([], [], [], []).
    

    product(_, [], [], _).
    

    但这还不够。

    你应该改变第三个子句

    product([], [_|T2], List3, [H4|T4]):-
        product([H4|T4], T2, List3, T4).
    

    product([], [_|T2], List3, L4):-
        product(L4, T2, List3, L4).
    

    我的意思是:使用保存的列表 1 是错误的。

    使用您的版本,来自

    product([1,2,3,4,5], [a,b,c,d], X),
    

    你只得到

    [[1,a],[2,a],[3,a],[4,a],[5,a],[1,b],[2,b],[3,b],[4,b],[5,b],[2,c],[3,c],[4,c],[5,c],[3,d],[4,d],[5,d]]
    

    也就是说:你松了[1,c][1,d][2,d]

    【讨论】:

      【解决方案3】:

      你应该改变条款:

      product([], [], [], []).
      

      到:

      product(_, [], [], _).
      

      这是因为当 L2 为空时,它会调用 product(L1,[],L3,L4) ,其中 L1 和 L4 不为空。您的基本情况必须是当 L2 为空(然后 L3 作为输出列表为空)并且其他列表可能包含元素时:

      ?- product([1,2,3], [a,b], X).
      X = [[1, a], [2, a], [3, a], [1, b], [2, b], [3, b]] ;
      false.
      

      【讨论】:

        猜你喜欢
        • 2011-03-24
        • 2013-04-20
        • 2021-11-19
        • 2021-02-17
        • 2011-01-26
        • 1970-01-01
        • 2014-02-01
        • 2015-05-14
        • 1970-01-01
        相关资源
        最近更新 更多