给定两个列表:L1 = [1,3,5]和L2 = [1,2,4],我需要编写代码以按排序顺序合并它们,因此结果将是L3 = [1,1 ,2,3,4,5]不使用cut operator
或fail
。我熟悉Prolog,我不知道如何解决这个问题。请问有谁请告诉我如何解决这个问题?我开始喜欢以下但是卡住了一段时间:
merge([], [], []).
merge([], L, L).
merge(L, [], L).
merge([H1|T1], [H2|T2], [L|Rest]:-
H1 =< H2 -> L = merge(H1
答案 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).