将两个列表合并到Prolog中

时间:2016-03-23 05:27:53

标签: prolog

给定两个列表:L1 = [1,3,5]和L2 = [1,2,4],我需要编写代码以按排序顺序合并它们,因此结果将是L3 = [1,1 ,2,3,4,5]不使用cut operatorfail。我熟悉Prolog,我不知道如何解决这个问题。请问有谁请告诉我如何解决这个问题?我开始喜欢以下但是卡住了一段时间:

merge([], [], []).
merge([], L, L).
merge(L, [], L).
merge([H1|T1], [H2|T2], [L|Rest]:-
    H1 =< H2 -> L = merge(H1

3 个答案:

答案 0 :(得分:2)

执行此操作的传统方法是使用compare/3。评估时,它将其第一个参数绑定到<=>。然后,您可以将此值用作辅助谓词的第一个参数:

...
compare(Order, X, Y),
merge_aux(Order, X, Y, Xs, Ys, Merged).

merge_aux(<, X, Y, ...
merge_aux(=, X, Y, ...
merge_aux(>, X, Y, ...

compare/3的调用是确定性的,对merge_aux的调用也是如此,因此您在任何时候都不需要削减。

答案 1 :(得分:0)

如果您以声明方式考虑它,那么您要描述的是一个合并,它包含两个已排序的附加列表。您可以将其划分为2个子任务:一个附加列表,另一个对结果列表进行排序。使用来自库(列表)的谓词append / 3和内置的谓词msort / 2,你可以直接在prolog中记下这个想法:

:- use_module(library(lists)).

merge(L1,L2,L3) :-
    append(L1,L2,X),
    msort(X,L3).

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

答案 2 :(得分:0)

如果您只想使用递归调用来执行此操作,可以尝试以下操作,我认为可能更有效地执行此操作。第一个递归子句指定如果列表X的头部大于列表Y的头部则执行的操作,第二个递归子句反之亦然。这将处理不同长度的列表。

我正在进行合并排序,所以现在需要解决剩下的问题。下一步如何将列表切成两半!

merge_ordered_lists([], [], []).
merge_ordered_lists(Xs, [], Xs).
merge_ordered_lists([], Ys, Ys).
merge_ordered_lists([X|Xs], [Y|Ys], [X|Rs]) :-
    X =< Y,
    merge_ordered_lists(Xs, [Y|Ys], Rs).
merge_ordered_lists([X|Xs],[Y|Ys], [Y|Rs]) :-
    X > Y,
    merge_ordered_lists([X|Xs], Ys, Rs).