我会建议这个练习:
编写一个方法插入,它有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).
但我认为只有一个元素的基本情况是多余的,因为我们有一般的递归情况和空列表一个,所以不需要。我需要一些建议来改进或更好的解释来完善代码。 谢谢你的时间。
答案 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元素进行比较。在
compare
或zcompare
第一个参数后,订单可以是>
或=
或<
(但这些是什么意思?可能猜测甚至可能会阅读文档,如果它不是太多的工作)。
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]).