Prolog插入列表

时间:2017-05-09 11:49:34

标签: prolog

我会建议这个练习:

  

编写一个方法插入,它有3个参数,第一个是有序的   列表,第二个是int,第三个是有序列表,没有重复   值等于第一个但包含第二个参数。

示例:

> insert([5, 6, 30, 60, 90], 40, L)
L = [5, 6, 30, 40, 60, 90]

> insert([5, 6, 30, 60, 90], 30, L)
L = [5, 6, 30, 60, 90]

我愿意:

insert([],_,[_]).

insert([H],_,Result) :-
Result < H,
insert([],[],[Result|H]).
insert([H],_,Result) :-
Result > H,
insert([],[],[H|Result]).

insert([H,Y|Rest], _, Result):-
_ < Y,
insert([X|Rest], [], Result).
insert([H,Y|Rest], _, Result):-
_ > Y,
insert([Y|Rest], [], Result).

但我认为只有一个元素的基本情况是多余的,因为我们有一般的递归情况和空列表一个,所以不需要。我需要一些建议来改进或更好的解释来完善代码。 谢谢你的时间。

2 个答案:

答案 0 :(得分:2)

尝试比较:

:- use_module(library(clpfd)).

insert([], X, [X]).
insert([X|Xs], New, Ys) :-
    zcompare(Order, X, New),
    insert(Order, X, New, Xs, Ys).

insert(>, X, New, Xs, [New,X|Xs]).
insert(=, X, _, Xs, [X|Xs]).
insert(<, X, New, Xs, [X|Ys]) :-
    insert(Xs, New, Ys).

但也许你需要解释?这很奇怪,因为你也可以像我一样阅读文档,并找到为什么这是足够好的实现,但当然也许最好解释一下,以防万一。

insert([], X, [X]).
  

当第一个参数为空列表时,第二个参数是结果列表的唯一元素。

insert([X|Xs], New, Ys) :-
    zcompare(Order, X, New), ...
  

当第一个参数是包含至少一个元素的列表时,取head元素并将其与New元素进行比较。在comparezcompare第一个参数后,订单可以是>=<(但这些是什么意思?可能猜测甚至可能会阅读文档,如果它不是太多的工作)。

insert(Order, X, New, Xs, Ys).
  

比较后,取下Order和其余变量......

insert(>, X, New, Xs, [New,X|Xs]).
  

列表头部的元素大于New元素。这意味着结果列表应该是New元素,后跟head,然后是list的其余部分。

insert(=, X, _, Xs, [X|Xs]).
  

列表头部的元素与New元素完全相同。我们完成了,不需要插入任何东西只保留原始列表作为结果。

insert(<, X, New, Xs, [X|Ys]) :-
    insert(Xs, New, Ys).
  

列表头部的元素小于New元素:新元素必须在结果中的此元素之后。因此我们将当前元素放回列表中并在列表的其余部分中搜索New元素的位置。

这么多文字,但是现在更容易理解代码说的是什么?也许或许没有?

?- insert([5, 6, 30, 60, 90], 40, L).
L = [5, 6, 30, 40, 60, 90].

?- insert([5, 6, 30, 60, 90], 6, L).
L = [5, 6, 30, 60, 90].

?- insert([5, 6, 30, 60, 90], 100, L).
L = [5, 6, 30, 60, 90, 100].

?- insert([5, 6, 30, 60, 90], 0, L).
L = [0, 5, 6, 30, 60, 90].

但是这个解决方案还有更多有趣的事情要做,因为它使用类似zcompare/3的谓词,看起来有点像compare/3,但它知道整数约束,因此可以查询:

  

可以在列表[1,3,4]中插入哪些整数?

?- insert([1,3,4], X, R).
R = [X, 1, 3, 4],
X in inf..0 ;
X = 1,
R = [1, 3, 4] ;
X = 2,
R = [1, 2, 3, 4] ;
X = 3,
R = [1, 3, 4] ;
X = 4,
R = [1, 3, 4] ;
R = [1, 3, 4, X],
X in 5..sup.

所以你可以插入任何整数&lt; 1在前面,或者你可以&#34;插入&#34; 1在那里,或者你可以在1和3之间插入2,或者你可以&#34;插入&#34; 3或4,或者您可以在列表末尾插入5或更大的内容。

答案 1 :(得分:0)

另一种方式:

% First element of the list is smaller than V
% we keep on wth the rest of the list
insert([H | T], V, [H|V1]) :-
    H < V, !, % remove choice points
    insert(T, V, V1).

% First element of the list is equal than V
% insert([V | T] , V, [V|T]).
% corrected after **enoy** remark
insert([V | T] , V, [V|T]):- !.

% First element of the list is greater than V, found the place of V
insert([H | T] , V, [V,H|T]).

% insert V in an empty list (V is greater than all elements of the list)
insert([], V, [V]).

Users9213 答案的结果相同。

编辑避免削减的方法是

% First element of the list is smaller than V
% we keep on with the rest of the list
insert([H | T], V, [H|V1]) :-
    H < V,
    insert(T, V, V1).

% First element of the list is equal than V
insert([V | T] , V, [V|T]).

% First element of the list is greater than V, found the place of V
insert([H | T] , V, [V,H|T]):-
    H > V.

% insert V in an empty list (V is greater than all elements of the list)
insert([], V, [V]).