【问题标题】:Writing a union operation in prolog for multisets在 prolog 中为多集编写联合操作
【发布时间】:2021-07-04 19:26:36
【问题描述】:

在序言中有一个标准的方法来定义两个集合的联合
但我想为多集编写联合函数。这意味着如果第一组有 [1,2] 和
第二个有 [2,3] 那么输出应该是 [1,2,2,3]。
我该如何编写这样的函数。

【问题讨论】:

    标签: prolog multiset


    【解决方案1】:

    Prolog 中没有 Set 类型。您所引用的只是列表。 union 谓词将两个具有假定唯一元素的列表组合到一个新列表中,其中元素再次唯一。一组中的顺序无关紧要。当你传递一个无序/非集合列表时,你会看到这一点。

    % both ordered, but result is not
    ?- union([1, 2, 5, 6], [3, 4, 7, 8], S).
    S = [1, 2, 5, 6, 3, 4, 7, 8].
    
    % sets, not ordered
    ?- union([1, 2, 3], [3, 2, 4, 5], S).
    S = [1, 3, 2, 4, 5].
    
    % multisets, not ordered
    ?- union([1, 2, 3], [3, 2, 4, 5, 5], S).
    S = [1, 3, 2, 4, 5, 5].
    

    要创建一个多重集,即保留集合并集中的所有元素,您可以只组合列表,同时按照您的意愿对它们进行排序。形式上,多重集也没有排序,所以如果排序无关紧要,您可以将第二个列表附加到第一个列表,这也适用于您的示例:

    ?- append([1, 2, 4], [2, 3, 4, 5], S).
    S = [1, 2, 4, 2, 3, 4, 5].
    
    ?- append([1, 2], [2, 3], S).
    S = [1, 2, 2, 3].
    

    如果您可以假设列表是有序的,并且您希望结果是这种情况,您可以合并它们,这样可以保持顺序:

    ?- merge([1, 2, 4], [2, 3, 4, 5], S).
    S = [1, 2, 2, 3, 4, 4, 5].
    

    如果您不能假设要对列表进行排序,但希望对结果进行排序,您也可以自己处理排序,例如与 msort:

    ?- append([1, 2, 3], [3, 2, 4, 5, 5], S), msort(S, S1).
    S = [1, 2, 3, 3, 2, 4, 5, 5],
    S1 = [1, 2, 2, 3, 3, 4, 5, 5].
    

    还有更多的排序谓词,如果更复杂你也可以自己写一个。

    【讨论】:

    • 我让工会工作了。我需要一些关于子集的帮助 - subset([],_). subset([X|L],Set):- member(X,Set),subset(L,Set). 这是普通子集的代码,但现在该集合是一个多重集,因此我需要从 Set 中删除 X,然后检查 L 是否为Set 的一个子集。如何在序言中做到这一点
    • 我不完全明白这将如何使它成为一个多集检查。但是您可以使用delete (Set, X, NewSet) 创建一个没有X 的新集合。
    • union 谓词将两个列表与假定的有序唯一元素相结合”我相信您的示例表明union 假定元素在每个列表中都是唯一的,但不是有序的,我错了吗?如果它假定要对列表进行排序,您将得到[1, 2, 3, 2, …] 而不是[1, 3, 2, …]
    • @Maëlan 你是对的,我把它和ord_union 混淆了。将纠正答案。
    • 我要实现的联合示例 - A = {a; a; b; b; b; c; d; d}; B = {b; b; c; c; c; d; d; e} A U B = {a; a; b; b; b; c; c; c; d; d; e} 所有元素最大计数。元素的顺序在输出中并不重要
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-19
    • 2016-06-28
    • 2022-08-11
    • 1970-01-01
    • 1970-01-01
    • 2012-02-21
    • 2020-12-22
    相关资源
    最近更新 更多