【问题标题】:Prolog merge two listsProlog合并两个列表
【发布时间】:2016-01-12 03:57:12
【问题描述】:

我需要在 Prolog 中合并两个列表。输入应该是谓词merge/3

应该像这样工作:

?- merge([6,4,b,8], [5,b,s,6], X).
X = [6, 4, b, 8, 5, s].

我尝试过的:

%rules
merge(A, B, X):- 
    merge(A, B, B, X).

merge([], X, _, X).
merge([Head|L1], [Head|L2], Tmp, [Head|X]) :-
    merge(L1, L2, Tmp, X),
    !.
merge(L1, [_|L2], Tmp, X) :-
    merge(L1, L2, Tmp, X),
    !.
merge([A|L1], [], Tmp, [A|X]) :-
    merge(L1, Tmp, Tmp, X),
    !.

我得到了什么:

?- merge([1,2,a,3], [5,d,a,1], X).
X = [1, 2, a, 3, 5, d, a, 1].

我的期望:

?- merge([1,2,a,3], [5,d,a,1], X).
X = [1, 2, a, 3, 5, d].

【问题讨论】:

    标签: list recursion merge prolog


    【解决方案1】:

    如果元素的顺序不依赖于两个输入列表的顺序,这是一个惯用的 Prolog 解决方案:

    ?- append([6,4,b,8], [5,b,s,6], A), sort(A, B).
    A = [6, 4, b, 8, 5, b, s, 6],
    B = [4, 5, 6, 8, b, s].
    

    如果顺序很重要,您需要说明具体如何。

    还有一些关于您显示的代码的 cmets。您为谓词选择的名称:“join”和“merge”都具有与您似乎试图实现的含义不同的明确含义(“join”在关系数据库中,“合并”,如“合并两个有序列表”)。你正在做的是一个"union"(顺便说一下,点击这个链接并阅读代码!)。

    此外,将cut 作为子句主体的最后一个子目标几乎总是一个错误(不是错误,而是错误)。有多个不明显互斥的谓词子句(作为 merge/4 的 4 个子句中的最后 3 个)通常是设计缺陷(不是错误)。

    【讨论】:

    • 非常感谢,但我必须在不使用内置谓词的情况下使用递归来做到这一点。我有这样的任务。 sites.google.com/site/prologsite/prolog-problems/1 如果有人能解释我如何做到这一点,那将非常高兴。所以我必须得到准确的答案 X = [6, 4, b, 8, 5, s]。
    • @InQuirer 除了“我需要什么”和“我试过什么”之外,你的问题至少应该有以下内容:“我得到了什么”和“我的理解问题到底是什么”为什么我没有得到我所期望的”。您还应该明确定义两个输入列表的元素顺序如何影响结果元素的顺序。
    • @InQuirer 我知道你不能告诉你的教授或讲师,但是“使用递归而不使用内置谓词来解决这个问题”太愚蠢了,甚至都不好笑......我为你感到抱歉:(
    【解决方案2】:

    这可以通过重写内置谓词来完成!例如:

    my_append([], R, R) .
    my_append([H|T], R1, [H|R2]) :-
        my_append(T, R1, R2).
    
    
    my_member(H, [H|_]).
    my_member(H, [_|T]) :-
        my_member(H, T).
    

    所以,我可以说将 L 与一个空列表合并得到这个列表 L

    merge(L, [], L).
    

    现在,为了合并两个列表,我查看第二个列表的第一个元素。

    如果它在第一个列表中,我将忽略它并将第一个列表与第二个列表的其余部分合并。

    如果没有,我将第一个元素添加到第一个列表的末尾,并将新的第一个列表与第二个列表的其余部分合并。

    不得不说效率不高!!

    merge(L, [H| T], R) :-
        (   my_member(H, L)
        ->  merge(L, T, R)
        ;   my_append(L, [H], L1),
            merge(L1, T, R)).
    

    【讨论】:

    • 谢谢,它完全可以正常工作。现在我将尝试了解如何。)
    猜你喜欢
    • 1970-01-01
    • 2013-02-07
    • 1970-01-01
    • 2011-08-26
    • 1970-01-01
    • 2014-03-19
    • 2012-02-23
    相关资源
    最近更新 更多